为什么这个正则表达式不起作用?也许是因为双重外观?

时间:2012-12-28 01:55:04

标签: python regex python-3.x

我有这个正则表达式:(?<![A-Z])(?<=[.!?])\s(?=[A-Z]) 它将一个段落分成句子(基于每个空格)。

我在这段话中使用了它:Did he know that J. Smith is a name? The term is most commonly applied to the placing of a warship in active duty with its country's military forces. The ceremonies involved are Often rooted in centuries old naval tradition. I.D. is a wonderful word.

它打破了“J.史密斯”,因为它认为“。”代表句子的结尾。

我正在使用re.split()并打印出数组,用新行分隔值

这是上段的输出:

Did he know that J.
Smith is a name?
The term is most commonly applied to the placing of a warship in active duty with its
country's military forces. (no newline at beginning of sentence)
The ceremonies involved are Often rooted in centuries old naval tradition.
I.D. is a wonderful word.`

适用于“I.D.”但为什么不为“J.史密斯”呢?从逻辑上讲,它应该......

我希望它在字符串中检测到这个结构:

没有大写字母+句号/?/!+空格+大写字母

2 个答案:

答案 0 :(得分:4)

lookbehind(或lookahead)是一个零宽度断言 - 也就是说,它在断言为真的任何点匹配零长度字符串。

特别是,这意味着,如果你的正则表达式中有两个连续的lookbehind(或超前)断言,只有当它们在同一点匹配时才会匹配

因此,(?<![A-Z])(?<=[.!?])匹配,如果前一个字符不是A-Z 范围内的大写字母,而,如果它是字符.!?之一。显然,后一种断言暗示了前者,因此正则表达式的(?<![A-Z])部分没有实际效果。

看起来你想要断言的是前一个字符是.!?之前的字符不是大写字母。如果是这样,一种解决方案是将(?<![A-Z])替换为(?<![A-Z].)


聚苯乙烯。您的原始正则表达式未拆分“I.D. is”的原因是\s匹配的第一个点后面没有空格,第二个句点后面的空格后面没有大写字母按照你的前瞻断言的要求。

答案 1 :(得分:3)

除了@ unutbu的观点,它可能没有按照你的期望做,因为你在同一个角色上断言两个看守,你说的是,“前一个角色不是{{ 1}}和它 [A-Z]。“也许你的意思是嵌套它们,例如

[.!?]