msg198116 - (view) |
Author: Jason Stumpf (Jason.Stumpf) |
Date: 2013-09-19 22:28 |
|
|
|
|
|
>>> re.match('(a|ab)*',('aba')).group(0) 'a' According to the documentation, the * should match as many repetitions as possible. 2 are possible, it matches 1. Reversing the order of the operands of |
changes the behaviour. >>> re.match('(ab |
a)*',('aba')).group(0) 'aba' |
|
|
|
|
|
msg198119 - (view) |
Author: janzert (janzert) * |
Date: 2013-09-19 22:52 |
|
|
|
|
|
The documentation on the | operator in the re module pretty explicitly covers this. http://docs.python.org/2/library/re.html "A |
B, where A and B can be arbitrary REs, creates a regular expression that will match either A or B. An arbitrary number of REs can be separated by the ' |
' in this way. This can be used inside groups (see below) as well. As the target string is scanned, REs separated by ' |
' are tried from left to right. When one pattern completely matches, that branch is accepted. This means that once A matches, B will not be tested further, even if it would produce a longer overall match. In other words, the ' |
' operator is never greedy." |
|
|
|
msg198120 - (view) |
Author: Jason Stumpf (Jason.Stumpf) |
Date: 2013-09-19 23:18 |
|
|
|
|
|
Even with the documentation to |, the documentation to * is wrong. >>> re.match('(a |
ab)*c',('abac')).group(0) 'abac' From the doc: In general, if a string p matches A and another string q matches B, the string pq will match AB. Since '(a |
ab)*c' matches 'abac', and 'c' matches 'c', that means '(a |
ab)*' matches 'aba'. It does so with 2 repetitions. Thus, in the example from my initial post, it was not matching with as many repetitions as possible. I think what you mean is that * attempts to match again after each match of the preceding regular expression. |
|
|
|
|
msg198121 - (view) |
Author: Jason Stumpf (Jason.Stumpf) |
Date: 2013-09-19 23:29 |
|
|
|
|
|
Sorry, that implication was backwards. I don't think I can prove from just the documentation that '(a|ab)*' can match 'aba' in certain contexts. If the docs said: "* attempts to match again after each match of the preceding regular expression." I think it would describe the observed behaviour. |
|
|
|
|
|
|
|
msg198122 - (view) |
Author: Matthew Barnett (mrabarnett) *  |
Date: 2013-09-20 00:00 |
|
|
|
|
|
The behaviour is correct. Here's a summary of what's happening:- First iteration of the repeated group: Try the first branch. Can match "a". Second iteration of the repeated group: Try the first branch. Can't match "a". Try the second branch. Can't match "ab". Continue with the remainder of the pattern. Can't match "c", therefore backtrack to the first iteration of the repeated group: Try the second branch. Can match "ab". Second iteration of the repeated group: Try the first branch. Can match "a". Third iteration of the repeated group: Try the first branch. Can't match "a". Try the second branch. Can't match "ab". Continue with the remainder of the pattern. Can match "c". Reached the end of the pattern. It has matched "abac". |
|
|
|
|
|
|
|
msg198123 - (view) |
Author: Jason Stumpf (Jason.Stumpf) |
Date: 2013-09-20 00:02 |
|
|
|
|
|
I understand what's happening, but that is not what the documentation describes. If the behaviour is correct, the documentation is incorrect. |
|
|
|
|
|
|
|
msg198126 - (view) |
Author: R. David Murray (r.david.murray) *  |
Date: 2013-09-20 01:36 |
|
|
|
|
|
The documentation is correct and unambiguous. Regular expressions just aren't very intuitive. The documentation says "Causes the resulting RE to match 0 or more repetitions of the preceding RE, as many repetitions as are possible." "as many repetitions of the preceding RE" means that: (a|ab)* is equivalent to (a |
ab)(a |
ab)(a |
ab)... where "..." represents "add copies of the RE until it doesn't match". Then you have to look at the documentation of ' |
' to see what it matches, and that documentation (already quoted) explains why the expanded pattern only matches 'a' in 'aba'. Perhaps it would be clearer if it read "Causes the RE to be evaluated as if there were zero or more repetitions of the preceding RE, as many repetitions as produce matches"? |
|
|
|
msg198152 - (view) |
Author: Jason Stumpf (Jason.Stumpf) |
Date: 2013-09-20 17:06 |
|
|
|
|
|
I like that clearer description. "as produce matches" is more correct than "as possible". |
|
|
|
|
|
|
|
msg224479 - (view) |
Author: Serhiy Storchaka (serhiy.storchaka) *  |
Date: 2014-08-01 09:38 |
|
|
|
|
|
I think this issue can be closed. Behavior and documentation are correct and match one other. Nothing to do with it. |
|
|
|
|
|
|
|
msg224781 - (view) |
Author: Ezio Melotti (ezio.melotti) *  |
Date: 2014-08-04 23:10 |
|
|
|
|
|
I agree. |
|
|
|
|
|
|
|
msg225180 - (view) |
Author: Akira Li (akira) * |
Date: 2014-08-11 09:27 |
|
|
|
|
|
tl;dr: added patch that clarifies Python re behavior. Please, review. --- The documented behavior is not clear: why (a|ab)* is not equivalent to (a |
ab)(a |
ab) for aba if the docs say "as many repetitions as are possible"? And it is not obvious (it is not the only possible behavior) e.g., POSIX [1] expects the longest match, PCRE [2] group may be atomic (/possesive quantifiers), or there is ungreedy repetition: $ echo abac |
grep -o '\(a\ |
ab\)* # Basic Regular Expression aba $ echo abac |
grep -Eo '(a |
ab)*' # Extended Regular Expression aba $ echo abac |
grep -Po '(a |