code: def first_match(string, regex, flags=re.M):
      
      if isinstance(string, Protocol):
          string = string.response
      return _first_match(string, re.compile(regex, flags))
docs: Matches the given string against the given regex.
  
        - If no match is found and the regular expression has zero or one
          groups, this function returns None.
  
        - If no match is found and the regular expression has more than one
          group, this function returns a tuple of None. The number of elements
          in the tuple equals the number of groups in the regular expression.
  
        - If a match is found and the regular expression has no groups,
          the entire string is returned.
  
        - If a match is found and the regular expression has one group,
          the matching string from the group is returned.
  
        - If a match is found and the regular expression has multiple groups,
          a tuple containing the matching strings from the groups is returned.
  
      This behavior ensures that the following assignments can never fail::
  
         foo   = 'my test'
         match = first_match(foo, r'aaa')         # Returns None
         match = first_match(foo, r'\S+')         # Returns 'my test'
         match = first_match(foo, r'(aaa)')       # Returns None
         match = first_match(foo, r'(\S+)')       # Returns 'my'
         match = first_match(foo, r'(aaa) (\S+)') # Returns (None, None)
         match = first_match(foo, r'(\S+) (\S+)') # Returns ('my', 'foo')
  
      :type  string: string|Exscript.protocols.Protocol
      :param string: The string that is matched, or a Protocol object.
      :type  regex: string
      :param regex: A regular expression.
      :type  flags: int
      :param flags: The flags for compiling the regex; e.g. re.I
      :rtype:  string|tuple
      :return: A match, or a tuple of matches.