我有一系列令牌可以捕获:
sweet (capture)
SWEETENED (capture)
not sweet (do not capture)
bitterly sweet (do not capture)
现在,我写了这个正则表达式,但它不符合我的要求:
^(?!not)^(?!bitterly)(sweet|SWEET|Sweet)(ed|ED)?
此表达式不捕获任何术语。我应该用什么来预测它?
P.S。我正在使用Python
答案 0 :(得分:3)
如果在模式中定义了捕获组,则可以使用仅返回捕获组值的re.findall
。您只需要匹配您想要忽略的内容,并匹配并捕获您需要获取的内容。但是,当捕获组无法匹配时,它也会返回空元素,这就是为什么filter(None, results)
会派上用场。
import re
s = '''sweet (capture)
SWEETENED (capture)
not sweet (do not capture)
bitterly sweet (do not capture)'''
print(filter(None, re.findall(r'\b(?:bitterly|not)\s+sweet|\b(sweet\w*)\b', s, flags=re.I)))
# => ['sweet', 'SWEETENED']
下面,
\b(?:bitterly|not)\s+sweet
- 匹配整个单词bitterly
或not
,后跟1 +空格和sweet
substring |
- 或\b(sweet\w*)\b
- 一个完整的单词sweet
,其后有任何其他单词字符(您可以使用自己的模式代替\w*
)flags=re.I
- 使模式不区分大小写。请参阅regex demo(只有代码才会保留绿色文本。)
关于消极的后视方法的几句话:在这种情况下我不认为它是好的,因为Python re
中的lookbehinds是固定宽度的,并且lookbehind中的所有替代方案必须具有相同的宽度。
您可以使用
(?i)(?<!\bbitterly )(?<!\bnot )\bsweet\w*
(请参阅demo),但如果bitterly
或sweet
之间有2或3个空格,则会失败。
另一个有趣的解决方案是使用PyPi正则表达式模块,您可以使用可变宽度的lookbehinds:
import regex
s='''sweet (capture)
SWEETENED (capture)
not sweet (do not capture)
bitterly sweet (do not capture)'''
rx = r'(?<!\b(?:bitterly|not)\s+)\bsweet\w*\b'
print(regex.findall(rx, s, flags=regex.I))
# => ['sweet', 'SWEETENED']
只有在前面没有sweet
模式的情况下,才会匹配整个单词\b(?:bitterly|not)\s+
(末尾有任何单词字符)。
答案 1 :(得分:0)
除了@ Wiktor的回答,模仿(*SKIP)(*FAIL)
你可能会与否定相处。先行:
(?!.*\b(?:not|bitterly))(?i)sweet(?:ened)?
<小时/>
缺点(可能?):not
和bitterly
的位置没有被考虑在内,因此像这样的句子
sweet and not sour
没有匹配。由你来决定是否需要这个。