正则表达式只绕过三个点

时间:2014-07-12 07:25:08

标签: python regex

我有这个字符串:

z='Certainly. I like apples... Really? By all means. Yes!'

我想捕获.?!但不捕获...子字符串,因此所需的输出应为:

['.', '?', '.', '!']

这就是我所拥有的:

>>> re.findall('(?<!\.)[\.?!]', z)
['.', '.', '?', '.', '!']

此正则表达式还捕获...子字符串的第一个点。但如果我跑:

>>> re.findall('(?<!\.{2})[\.?!]', z)
['.', '.', '.', '?', '.', '!']

与我的预期完全相反,我不明白为什么因为我要求前瞻不匹配如果前面有两个点(尝试使用量词,任何运算符+?*{1,2}都会产生错误,因为看起来 - 后面需要固定宽度模式)。

我误解了一些东西,因为我希望在前瞻中添加第二个\.会产生我想要的输出。

我会很感激任何建议和简短的解释(找不到与我要求的完全相同的东西)。

2 个答案:

答案 0 :(得分:2)

你可以试试下面的正则表达式,使用负面的lookbehind和lookahead

>>> import re
>>> z='Certainly. I like apples... Really? By all means. Yes!'
>>> z
'Certainly. I like apples... Really? By all means. Yes!'
>>> m = re.findall(r'(?<!\.)[.?!](?!\.)', z)
>>> m
['.', '?', '.', '!']

DEMO

上述正则表达式匹配点.?!,这些点前面没有点,后面没有点。

答案 1 :(得分:2)

另一种可能性:

pat = re.compile(r"\.\.\.|([.?!])")
matches = filter(None, pat.findall(z))

这可以通过匹配文字...并消耗该字符串,然后我们有机会将其放入捕获组(在&#34; OR&#34;管道的另一端({{1然后过滤结果以删除所有|(这是''在找到与空捕获组匹配时使用的内容)。

一些人称之为The Best Regex Trick