Partidas superpuestas con finditer () en Python

Estoy usando una expresión regular para unir las referencias de los versículos de la Biblia en un texto. La expresión regular actual es

REF_REGEX = re.compile(''' (?<!\w) # Not preceded by any words (?Pq(?:uote)?\s+)? # Match optional 'q' or 'quote' followed by many spaces (?P (?:(?:[1-3]|I{1,3})\s*)? # Match an optional arabic or roman number between 1 and 3. [A-Za-z]+ # Match any alphabetics )\.? # Followed by an optional dot (?: \s*(?P\d+) # Match the chapter number (?: [:\.](?P\d+) # Match the starting verse number, preceded by ':' or '.' (?:-(?P\d+))? # Match the optional ending verse number, preceded by '-' )? # Verse numbers are optional ) (?: \s+(?: # Here be spaces (?:from\s+)|(?:in\s+)|(?P\()) # Match 'from[:space:]', 'in[:space:]' or '(' \s*(?P\w+) # Match a word preceded by optional spaces (?(lbrace)\)) # Close the '(' if found earlier )? # The whole 'in|from|()' is optional ''', re.IGNORECASE | re.VERBOSE | re.UNICODE) 

Esto coincide con las siguientes expresiones bien:

 "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'), 

pero no se puede analizar:

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

porque devuelve (None, 'in', '2', None, None, None, None) lugar.

¿Hay alguna forma de que finditer () devuelva todas las coincidencias, incluso si se superponen, o hay una manera de mejorar mi expresión regular para que coincida con este último bit correctamente?

Gracias.

Se consume un carácter consumido, no debe pedirle al motor de expresiones regulares que regrese.

De sus ejemplos, la parte del versículo (por ejemplo :1 ) parece no opcional. Eliminar eso coincidirá con el último bit.

 ref_regex = re.compile(''' (?\() # or stuff between (...) )\s*(\w+) (?(lbrace)\)) )? ''', re.X | re.U) 

(Si va a escribir un RegEx gigantesco como este, use la /x ).


Si realmente necesita coincidencias superpuestas, puede usar un lookahead. Un ejemplo simple es

 >>> rx = re.compile('(.)(?=(.))') >>> x = rx.finditer("abcdefgh") >>> [y.groups() for y in x] [('a', 'b'), ('b', 'c'), ('c', 'd'), ('d', 'e'), ('e', 'f'), ('f', 'g'), ('g', 'h')] 

Puedes extender esta idea a tu RegEx.