Author Alexander.Schmolck
Recipients Alexander.Schmolck
Date 2010-11-05.14:33:46
SpamBayes Score 8.96629e-07
Marked as misclassified No
Message-id <>
In certain cases a zero-width /Z match that should be replaced isn't.

An example might help:

 re.compile('(?m)(?P<trailing_ws>[ \t]+\r*$)|(?P<no_final_newline>(?<=[^\n])\Z)').subn(lambda m:next('<'+k+'>' for k,v in m.groupdict().items() if v is not None), 'foobar ')

this gives

 ('foobar<trailing_ws>', 1)

I would have expected

('foobar<trailing_ws><no_final_newline>', 2)

Contrast this with the following behavior:

 [m.span() for m in re.compile('(?P<trailing_ws>[ \t]+\r*$)|(?P<no_final_newline>(?<=[^\n])\Z)', re.M).finditer('foobar ')]

 [(6, 7), (7, 7)]

The matches are clearly not overlapping and the re module docs for sub say "Return the string obtained by replacing the leftmost non-overlapping occurrences of pattern in string by the replacement repl.", so I would have expected two replacements.

This seems to be what perl is doing:

 echo -n 'foobar ' | perl -pe 's/(?m)(?P<trailing_ws>[ \t]+\r*$)|(?P<no_final_newline>(?<=[^\n])\Z)/<$&>/g'                    

 foobar< ><>%
Date User Action Args
2010-11-05 14:33:48Alexander.Schmolcksetrecipients: + Alexander.Schmolck
2010-11-05 14:33:48Alexander.Schmolcksetmessageid: <>
2010-11-05 14:33:47Alexander.Schmolcklinkissue10328 messages
2010-11-05 14:33:46Alexander.Schmolckcreate