On Wed, Dec 4, 2019 at 9:18 AM Serhiy Storchaka <storchaka@gmail.com> wrote:
 > I think I am +1 on
 > adding re.findfirst() as proposed by the OP.

It is not clear what it should return. A Match object, a string, a
tuple, whatever? What should it return if no match found -- None, en
empty string, an empty tuple, error? I suppose that different users can
have different need. It is not practical to provide functions for all
combinations, it is easy to write a function for your needs using
re.search(). We can only add some receipts in the documentation.

The concrete user code can be a little bit simpler (one-liner) if we
provide an empty match object. For example:

     (re.search(patter.string) or EmptyMatch).groups()

Still pretty obscure. I propose that re.findfirst(...) should return the same thing as re.findall(...)[0] *if the findall() returns a non-empty list*, and otherwise it should return a default. The default defaults to None but can be set by passing default=... to the re.findfirst() call. For simple cases (no capturing groups, or a single one) that will return a string or the default value; if there are multiple capturing groups it will return a tuple of strings or the default. If the user always wants a tuple they can do so by specifying an appropriate tuple as default value; I don't propose to try and match the shape of the tuple on a successful match.

--Guido van Rossum (python.org/~guido)