classification
Title: re.compile("(.*$){1,4}", re.MULTILINE) fails
Type: Stage: resolved
Components: Regular Expressions Versions: Python 2.7
process
Status: closed Resolution: duplicate
Dependencies: Superseder: re.compile(r'((x|y+)*)*') should not fail
View: 2537
Assigned To: niemeyer Nosy List: BreamoreBoy, doko, niemeyer, schmir, serhiy.storchaka, timehorse
Priority: normal Keywords:

Created on 2007-01-12 10:45 by doko, last changed 2013-08-19 20:33 by serhiy.storchaka. This issue is now closed.

Messages (4)
msg61053 - (view) Author: Matthias Klose (doko) * (Python committer) Date: 2007-01-12 10:45
[forwarded from http://bugs.debian.org/289603]

Trying to match 1-4 lines of arbitrary content (as part of a larger regex) using the expression (.*$){1,4} and re.MULTILINE.  This caused the re module to raise the error "nothing to repeat".

$ python2.5
Python 2.5 (release25-maint, Dec 13 2006, 16:21:45) 
[GCC 4.1.2 20061212 (prerelease) (Ubuntu 4.1.1-21ubuntu2)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import re
>>> re.compile("(.*$){1,4}", re.MULTILINE)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python2.5/re.py", line 180, in compile
    return _compile(pattern, flags)
  File "/usr/lib/python2.5/re.py", line 233, in _compile
    raise error, v # invalid expression
sre_constants.error: nothing to repeat
msg74660 - (view) Author: Jeffrey C. Jacobs (timehorse) Date: 2008-10-11 17:24
On first blush, this issue sounds quite similar to issue 2537, but I 
have been looking at different scenarios and found that there is a 
subtle difference because, grammatically:

(?m)(?:.*$)(.*$)

is the same as:

(?m)(.*$){2}

Yet the former compiles while the later raises the exception you list 
below.  Thus, I think the issue YOU raise is indeed related to the 
redundant repeat operator issue numbered 2537, BUT, when I match an 
expression with the alternate form, I get an empty string in my capture 
group, since in a range repeat over a capture group, only the last group 
is captured, while the entire expression matches only the first line, 
without the end-line character.  Thus, the other thing to remember is 
that ^ and $ are zero-width matches, so when you write .*$, you are 
saying match up to, but not including, the end of the line.  If you 
immediately follow that with another .*$, you will start from the point 
"up to, but not including, the end of the line", which means the next 
character is an end of line.  Thus, when you reach the second .*$, you 
capture nothing because the .* is allowed to be zero-length and you 
still haven't advanced PAST the end of the line.

As a working alternative, you could write r'(?m)(?:(.*$)[\r\n]*){1,4}' , 
since this would give you your 1-4 lines, but also consume the carriage 
return and line feed characters to get you to the next line.

Since we don't want to change the meaning of $ and ^ to make them 
capturing (custom POSIX character classes may make 'capturing' a new 
line character easier), and the 'redundant repeat operator' is already 
listed as a bug (your expression is essentially saying (.*){1,4}$ 
because it does not capture the new-line character(s) and thus has a 
redundant repeat operation in the range repeat expression), I'm willing 
to call this a repeat (technically repeated by as this issue is older) 
of issue 2537.
msg116581 - (view) Author: Mark Lawrence (BreamoreBoy) * Date: 2010-09-16 17:37
Can this be closed as a duplicate of #2537?
msg195663 - (view) Author: Serhiy Storchaka (serhiy.storchaka) * (Python committer) Date: 2013-08-19 20:33
Fixed in issue2537. See also issue18647.
History
Date User Action Args
2013-08-19 20:33:07serhiy.storchakasetstatus: open -> closed

superseder: re.compile(r'((x|y+)*)*') should not fail

nosy: + serhiy.storchaka
messages: + msg195663
resolution: duplicate
stage: resolved
2010-09-16 17:37:43BreamoreBoysetnosy: + BreamoreBoy
messages: + msg116581
2008-10-11 17:24:59timehorsesetmessages: + msg74660
2008-09-28 19:25:09timehorsesetnosy: + timehorse
versions: + Python 2.7, - Python 2.5
2008-02-23 21:59:06schmirsetnosy: + schmir
2007-01-12 10:45:14dokocreate