Python中带负向后看的正则表达式

2024-04-23 17:20:57 发布

您现在位置:Python中文网/ 问答频道 /正文

我在熊猫数据框中有一系列的自由文本注释。我知道怎样才能识别那些与给定正则表达式匹配的字段,这些正则表达式后面包含一个否定的外观。作为一个简单的例子,我有如下字段:

frogs seen
green frog seen
no frogs seen
no green frogs seen
frogs not seen
green frogs not seen

我只想找出那些看到青蛙的线。在real dateset中,可能包含许多其他文本,并且显示的短语包含在较大的文本字符串中。我想到的正则表达式如下:

(?<!no\s)(?:(?:green\s)?frogs?\s)(?!not\s)(?:seen)?

这几乎奏效了。它与预期的“看到青蛙”和“看到绿青蛙”匹配。它也不符合“看不到青蛙”、“看不到青蛙”和“看不到绿青蛙”这正是我们想要的。然而,在短语“看不到绿色青蛙”中,正则表达式与文本“看到青蛙”匹配。你知道吗

据我所知,否定的look behinds只能是固定数量的字符(即不能使用*、+或?允许可变字符串长度)。我以为包括(?)?:绿色)在(?)?:青蛙?)非捕获组将努力找到整个组,如果前面有一个固定长度的负片,则否定它。然而,情况似乎并非如此。你知道吗

任何关于如何解决这个问题的建议都将不胜感激。你知道吗


Tags: 数据no字符串文本notgreenreal例子
2条回答

我相信,你的lookback不起作用的原因是因为你有(?:green\s)?,使“绿色”成为可选的。当扫描器到达'frog'时,它会向后看三个字符,寻找'no',但没有找到它,因此它接受'no green frogs seen'作为匹配。如果改为(?:green\s),那么“green”不是可选的,那么这个测试用例将被拒绝。因此,与其使用负向后看,不如尝试负向前看:

import re

test_cases = [
'frogs seen',
'green frog seen',
'no frogs seen',
'no green frogs seen',
'frogs not seen',
'green frogs not seen'
]

regex = re.compile(r'(?!no\s+)(?:(?:green\s+)?frogs?)(?=\s+seen)')
for test_case in test_cases:
    if re.match(regex, test_case):
        print(test_case)

印刷品:

frogs seen
green frog seen

我想出了这个正则表达式(regex101):

test_cases = [
'frogs seen',
'green frog seen',
'no frogs seen',
'no green frogs seen',
'frogs not seen',
'green frogs not seen'
]

import re

for test_case in test_cases:
    m = re.findall(r'^((?!(?:(?:\bno\b.*frogs?)|(?:frogs?.*\bnot\b.*seen))).)*$', test_case)
    if m:
        print('{} matches!'.format(test_case))

印刷品:

frogs seen matches!
green frog seen matches!

相关问题 更多 >