正则否定前瞻应用:关键词间无指定否定词时提取后续整数
问题描述
我有一个包含两个关键词keyword_1、keyword_2的字符串,keyword_2后跟随一个整数。我希望仅当特定否定关键词keyword_neg未出现在keyword_1与keyword_2之间时,提取该整数。此外,所有关键词之间可能存在随机文本。
尝试多种正则表达式均未成功:
- 第一个测试字符串本应返回空结果,却返回了数字9;
- 第二个测试字符串应返回数字5。
原始代码如下:
import re # 以下字符串应返回空,因为在"ISIN ABC123"和"Fondets omløpshastighet er"之间出现了"ISIN" str_that_should_return_nothing = "ISIN ABC123 blabla ISIN DEF123 Fondets omløpshastighet er 9 blabla" # 以下字符串应返回5,因为"ISIN ABC123"和"Fondets omløpshastighet er"之间没有出现"ISIN" str_that_should_return_5 = "ISIN ABC123 blabla Fondets omløpshastighet er 5 ISIN DEF123 Fondets omløpshastighet er 9 blabla" pattern = 'ISIN ABC123.*?(?!ISIN).*?Fondets omløpshastighet er (\d)' # 无效 match = re.findall(pattern, str_that_should_return_nothing ) print("str_1_f: ", match) match = re.findall(pattern, str_that_should_return_5) print("str_2_t: ", match)
解决方案
你之前的正则表达式失效原因是:(?!ISIN)是零宽负向预测断言,它仅检查当前位置后是否不是ISIN,无法阻止后续文本中出现该关键词。要实现"两关键词间不包含否定词"的逻辑,需要用逐字符检查的否定断言结构。
修正后的代码与正则
import re str_that_should_return_nothing = "ISIN ABC123 blabla ISIN DEF123 Fondets omløpshastighet er 9 blabla" str_that_should_return_5 = "ISIN ABC123 blabla Fondets omløpshastighet er 5 ISIN DEF123 Fondets omløpshastighet er 9 blabla" # 修正后的正则表达式 pattern = r'ISIN ABC123(?:(?!ISIN).)*?Fondets omløpshastighet er (\d+)' match = re.findall(pattern, str_that_should_return_nothing) print("str_1_f: ", match) # 输出: str_1_f: [] match = re.findall(pattern, str_that_should_return_5) print("str_2_t: ", match) # 输出: str_2_t: ['5']
正则逻辑解释
ISIN ABC123: 匹配起始关键词(?:(?!ISIN).)*?: 非捕获组,核心逻辑所在:(?!ISIN): 每匹配一个字符前,先检查当前位置后是否不是ISIN,确保区间内不会出现该否定关键词.: 匹配任意单个字符*?: 非贪婪匹配,避免跨过目标keyword_2匹配到后续内容
Fondets omløpshastighet er (\d+): 匹配结束关键词,并用\d+捕获后续整数(支持多位数,比\d更实用)
进阶优化(匹配独立单词)
如果需要确保ISIN是独立单词(避免匹配ISINXYZ这类包含ISIN的字符串),可以给关键词加上单词边界\b:
pattern = r'\bISIN ABC123\b(?:(?!\bISIN\b).)*?\bFondets omløpshastighet er\b (\d+)'
内容的提问来源于stack exchange,提问作者Spaniel
相关产品推荐
相关产品推荐

