On Dec 3, 2019, at 09:05, Serhiy Storchaka <storchaka@gmail.com> wrote:
Actually the semantic of the above code is different from the semantic of `re.findall(regex, text)[0]`. findall() yields strings if the pattern contains less than 2 capture groups and tuples if it more than 1 capture groups.
re.findall('..', 'abcd') ['ab', 'cd'] re.findall('(.).', 'abcd') ['a', 'c'] re.findall('((.).)', 'abcd') [('ab', 'a'), ('cd', 'c')]
It is not clear what behavior do you need. And I suppose that other users of findfirst() can need different behavior. search() is more powerful and allow you to get what you need.
I think the point is that there are cases (like interactive exploration in the REPL) where findall and finditer are more convenient despite being less powerful, and in fact they’re more convenient because of this weird inconsistency. You know that your particular regexp has no capture groups and you just want the matched strings. Or you know that it does have capture groups, and you want the matched tuples of strings. Either way, you don’t need the match object, and having to deal with that (and, worse, with a match object or None) is just extra code that gets in the way (and that you can get wrong). And I think the OP is right that there would be similar convenience uses for findfirst, if not even more of them. And it makes more sense to build that findfirst around findall or finditer than around search. But, given how easy it is to build this on finditer, and that it uses a general pattern that works for every similar case rather than something specific to regexp, I agree that nothing needs to be done (except maybe to educate people better about next).