docs: def replace_entities(entities, pattern):
      """
      Replaces all entity names in a given pattern with the corresponding
      values provided by entities.
  
      Args:
          entities (dict): A dictionary mapping entity names to entity values.
          pattern (str): A path pattern that contains entity names denoted
              by curly braces. Optional portions denoted by square braces.
              For example: 'sub-{subject}/[var-{name}/]{id}.csv'
              Accepted entity values, using regex matching, denoted within angle
              brackets.
              For example: 'sub-{subject<01|02>}/{task}.csv'
  
      Returns:
          A new string with the entity values inserted where entity names
          were denoted in the provided pattern.
      """
      ents = re.findall(r'\{(.*?)\}', pattern)
      new_path = pattern
      for ent in ents:
          match = re.search(r'([^|<]+)(<.*?>)?(\|.*)?', ent)
          if match is None:
              return None
          name, valid, default = match.groups()
          default = default[1:] if default is not None else default
  
          if name in entities and valid is not None:
              ent_val = str(entities[name])
              if not re.match(valid[1:-1], ent_val):
                  if default is None:
                      return None
                  entities[name] = default
  
          ent_val = entities.get(name, default)
          if ent_val is None:
              return None
          new_path = new_path.replace('{%s}' % ent, str(ent_val))
  
      return new_path