gpt4 book ai didi

python - 在 Python 中使用 finditer() 进行重叠匹配

转载 作者:太空宇宙 更新时间:2023-11-03 23:49:26 25 4
gpt4 key购买 nike

我正在使用正则表达式来匹配文本中的圣经经文引用。当前的正则表达式是

REF_REGEX = re.compile('''
(?<!\w) # Not preceded by any words
(?P<quote>q(?:uote)?\s+)? # Match optional 'q' or 'quote' followed by many spaces
(?P<book>
(?:(?:[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<chapter>\d+) # Match the chapter number
(?:
[:\.](?P<startverse>\d+) # Match the starting verse number, preceded by ':' or '.'
(?:-(?P<endverse>\d+))? # Match the optional ending verse number, preceded by '-'
)? # Verse numbers are optional
)
(?:
\s+(?: # Here be spaces
(?:from\s+)|(?:in\s+)|(?P<lbrace>\()) # Match 'from[:space:]', 'in[:space:]' or '('
\s*(?P<version>\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)

这很好地匹配了以下表达式:

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

但是解析失败:

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

因为它返回 (None, 'in', '2', None, None, None, None) 而不是。

有没有办法让 finditer() 返回所有匹配项,即使它们重叠,或者有没有办法改进我的正则表达式,使其正确匹配最后一位?

谢谢。

最佳答案

消耗的字符被消耗了,你不应该要求正则表达式引擎返回。

从你的例子来看,诗句部分(例如 :1)似乎不是可选的。删除它将匹配最后一位。

ref_regex = re.compile('''
(?<!\w) # Not preceeded by any words
((?i)q(?:uote)?\s+)? # Match 'q' or 'quote' followed by many spaces
(
(?:(?:[1-3]|I{1,3})\s*)? # Match an arabic or roman number between 1 and 3.
[A-Za-z]+ # Match many alphabetics
)\.? # Followed by an optional dot
(?:
\s*(\d+) # Match the chapter number
(?:
[:.](\d+) # Match the verse number
(?:-(\d+))? # Match the ending verse number
) # <-- no '?' here
)
(?:
\s+
(?:
(?i)(?:from\s+)| # Match the keyword 'from' or 'in'
(?:in\s+)|
(?P<lbrace>\() # or stuff between (...)
)\s*(\w+)
(?(lbrace)\))
)?
''', re.X | re.U)

(如果您要编写这样一个巨大的 RegEx,请使用 /x 标志。)


如果你真的需要重叠匹配,你可以使用前瞻。一个简单的例子是

>>> 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')]

您可以将这个想法扩展到您的 RegEx。

关于python - 在 Python 中使用 finditer() 进行重叠匹配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3027718/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com