关于python:为什么这个regex不工作?可能是因为长了一双眼睛?

Why does this regex not work? Maybe because of double lookbehinds?

我有这个regex:(?它把一个段落分成句子(基于每个空格)。

我在这段话中用过: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.Smith",因为它认为"."代表句子的结尾。

我使用re.split()并打印出数组,用换行符分隔值

这是以上段落的输出:

1
2
3
4
5
6
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.`

它适用于"身份证",但为什么不适用于"J.史密斯"?从逻辑上讲,它应该…

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

无大写字母+句点/?!+空白+大写字母


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

特别是,这意味着,如果在regexp中有两个连续的lookbehind(或lookahead)断言,那么只有当它们在同一点上匹配时,它们才会匹配。

因此,如果前一个字符不是A-Z范围内的大写字母,并且是.!?字符之一,则(?匹配。显然,后一个断言意味着前一个,所以regexp的(?部分没有实际效果。

你想断言的是,前面的字符是.!?的,前面的字符不是大写字母。如果是这样,一种解决方案是用(?替换(?

另外,您的原始regex没有拆分"I.D. is"的原因是,\s匹配的第一个点后没有空格,第二个周期后的空格后面没有您的前瞻性声明所要求的大写字母。


除了@unutbu的观点外,它可能不会像你所期望的那样做,因为你在断言两个lookbehind在同一个字符上,也就是说,"前一个字符不是[A-Z],它是[.!?]。"也许你的意思是嵌套它们,例如。

1
(?<=(?<![A-Z])[.!?])\s(?=[A-Z])