[Python-Dev] Zero-width matching in regexes
Serhiy Storchaka
storchaka at gmail.com
Wed Dec 6 08:13:46 EST 2017
05.12.17 22:26, Terry Reedy пише:
> On 12/4/2017 6:21 PM, MRAB wrote:
>> I've finally come to a conclusion as to what the "correct" behaviour
>> of zero-width matches should be: """always return the first match, but
>> never a zero-width match that is joined to a previous zero-width
>> match""".
>
> Is this different from current re or regex?
Partially. There are different ways of handling the problem of repeated
zero-width searching.
1. The one formulated by Matthew. This is the behavior of findall() and
finditer() in regex in both VERSION0 and VERSION1 modes, sub() in regex
in the VERSION1 mode, and findall() and finditer() in re since 3.7.
2. Prohibit a zero-width match that is joined to a previous match
(independent from its width). This is the behavior of sub() in re and in
regex in the VERSION0 mode, and split() in regex in the VERSION1 mode.
This is the only correctly documented and explicitly tested behavior in re.
3. Prohibit a zero-width match (always). This is the behavior of split()
in re in 3.4 and older (deprecated since 3.5) and in regex in VERSION0 mode.
4. Exclude the character following a zero-width match from following
matches. This is the behavior of findall() and finditer() in 3.6 and older.
The case 4 is definitely incorrect. It leads to excluding characters
from matching. re.findall(r'^|\w+', 'two words') returns ['', 'wo',
'words'].
The case 3 is pretty useless. It disallow splitting on useful zero-width
patterns like `\b` and makes `\s*` just equal to `\s+`.
The difference between cases 1 and 2 is subtle. The case 1 looks more
logical and matches the behavior of Perl and PCRE, but the case 2 is
explicitly documented and tested. This behavior is kept for
compatibility with an ancient re implementation.
More information about the Python-Dev
mailing list