我了解如何在Python中使匹配大小写不区分大小写,并且了解如何使用前瞻性/后备性,但是如何将两者结合起来?
例如,我的文字是
mytext = I LOVE EATING popsicles at home.
我想从这段文字(我的目标食品)中提取popsicles
。此正则表达式效果很好:
import re
regex = r'(?<=I\sLOVE\sEATING\s)[a-z0-9]*(?=\sat\shome)'
re.search(regex, mytext)
但是,我想说明有人写作的情况
i LOVE eating apples at HOME.
应该匹配。但是"I LOVE eating Apples at home"
不应该匹配,因为Apples
是大写。
因此,我希望在两个(?=\sat\shome)
前行和(?<=I\sLOVE\sEATING\s)
后行中具有本地区分大小写。我知道我可以对全局不区分大小写使用re.IGNORECASE
标志,但是我只希望超前/后退组不区分大小写,而不是我的实际目标表达式。
通常,我会在(?i:I LOVE EATING)
之前创建一个不区分大小写的非捕获组,该组能够匹配I LOVE EATING
和I love eating
。但是,如果我尝试将两者结合在一起:
(?i:<=I\sLOVE\sEATING\s)
我没有匹配项,因为它现在将i:
解释为要匹配的文字表达式。有没有一种方法可以将区分大小写的内容与前瞻性内容结合在一起?
编辑:我认为这不是已标记问题的重复。这个问题专门询问一个小组的一部分-我要求一个特定的子集-向前和向后看。这里的语法不同。该其他帖子中的答案并不直接适用。正如该帖子的答案所建议的那样,您需要采取一些变通方法来实现此功能,而这些功能不适用于所谓的重复SO帖子。
答案 0 :(得分:2)
很遗憾,python re
module doesn't allow inline use of mode modifiers in the middle of a regex。
作为解决方法,您可以使用以下正则表达式:
reg = re.compile(r'(?<=[Ii]\s[Ll][Oo][Vv][Ee]\s[Ee][Aa][Tt][Ii][Nn][Gg]\s)[a-z0-9]*(?=\s[Aa][Tt]\s[Hh][Oo][Mm][Ee])')
print "Case 1: ", reg.findall('I LOVE Eating popsicles at HOME.')
print "Case 2: ", reg.findall('I LOVE EATING popsicles at home.')
print "Case 3: ", reg.findall('I LOVE Eating Popsicles at HOME.')
输出:
Case 1: ['popsicles']
Case 2: ['popsicles']
Case 3: []
答案 1 :(得分:2)
您可以使用(?i)
将正则表达式全局设置为不区分大小写,并使用(?-i:groupcontent)
将组切换为不区分大小写:
regex = r'(?i)(?<=I\sLOVE\sEATING\s)(?-i:[a-z0-9]*)(?=\sat\shome)'
您也可以在搜索中使用(?i)
代替re.I
。以下等效于上述正则表达式:
regex = r'(?<=I\sLOVE\sEATING\s)(?-i:[a-z0-9]*)(?=\sat\shome)'
re.search(regex, mytext, re.I)
答案 2 :(得分:2)
使用(?i:...)
可以为正则表达式设置标志(在这种情况下为i
)
本地(内联)用于正则表达式的某些部分。
在lookbehind或 先行,同时保持其余正则表达式不带任何选择。
我修改了您的代码,因此它会一次编译正则表达式 对于不同的字符串,调用次数是2次:
mytext1 = 'i LOVE eating Apples at HOME.'
mytext2 = 'i LOVE eating apples at HOME.'
pat = re.compile(r'(?<=(?i:I\sLOVE\sEATING\s))[a-z0-9]+(?=(?i:\sAT\sHOME))')
m = pat.search(mytext1)
print('1:', m.group() if m else '** Not found **')
m = pat.search(mytext2)
print('2:', m.group() if m else '** Not found **')
它打印:
1: ** Not found **
2: apples
因此匹配项仅适用于第二个源字符串。