Overlapping matches with finditer() in Python

Posted by Raphink on Stack Overflow See other posts from Stack Overflow or by Raphink
Published on 2010-06-12T06:16:27Z Indexed on 2010/06/12 6:22 UTC
Read the original article Hit count: 359

Hi there,

I'm using a regex to match Bible verse references in a text. The current regex is

REF_REGEX = re.compile(r'(?<!\w)((?i)q(?:uote)?\s+)?((?:(?:[1-3]|I{1,3})\s*)?[A-Za-z]+)\.?(?:\s*(\d+)(?:[:.](\d+)(?:-(\d+))?)?)(?:\s+(?:(?i)(?:from\s+)|(?:in\s+)|(?P<lbrace>\())\s*(\w+)(?(lbrace)\)))?', re.UNICODE)

This matches the following expressions fine:

"jn 3:16":                           (None, 'jn', '3', '16', None, None, None),
"matt. 18:21-22":                    (None, 'matt', '18', '21', '22', None, None),
"q matt. 18:21-22":                  ('q ', 'matt', '18', '21', '22', None, None),
"QuOTe jn 3:16":                     ('QuOTe ', 'jn', '3', '16', None, None, None),
"q 1co13:1":                         ('q ', '1co', '13', '1', None, None, None), 
"q 1 co 13:1":                       ('q ', '1 co', '13', '1', None, None, None),
"quote 1 co 13:1":                   ('quote ', '1 co', '13', '1', None, None, None),
"quote 1co13:1":                     ('quote ', '1co', '13', '1', None, None, None),
"jean 3:18 (PDV)":                   (None, 'jean', '3', '18', None, '(', 'PDV'),
"quote malachie 1.1-2 fRom Colombe": ('quote ', 'malachie', '1', '1', '2', None, 'Colombe'),
"quote malachie 1.1-2 In Colombe":   ('quote ', 'malachie', '1', '1', '2', None, 'Colombe'),
"cinq jn 3:16 (test)":               (None, 'jn', '3', '16', None, '(', 'test'),
"Q   IIKings5.13-58   from   wolof": ('Q     ', 'IIKings', '5', '13', '58', None, 'wolof'),
"This text is about lv5.4-6 in KJV only": (None, 'lv', '5', '4', '6', None, 'KJV'),

but it fails to parse:

"Found in 2 Cor. 5:18-21 ( Ministers":                    (None, '2 Cor', '5', '18', '21', None, None),

because it returns (None, 'in', '2', None, None, None, None) instead.

Is there a way to get finditer() to return all matches, even if they overlap, or is there a way to improve my regex so it matches this last bit properly?

Thanks.

© Stack Overflow or respective owner

Related posts about python

Related posts about regex