1

我有这个正则表达式:(?<![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. Smith”,因为它认为“。” 代表一个句子的结束。

我正在使用 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.`

它适用于“ID”,但为什么不适用于“J. Smith”?逻辑上应该...

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

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

4

2 回答 2

4

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

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

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

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


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

于 2012-12-28T02:27:01.760 回答
3

除了@unutbu 的观点之外,它可能没有按照您的预期进行,因为您在同一个角色上断言两个后视,您说,“前一个角色不是[A-Z],它 [.!?]。” 也许你的意思是嵌套它们,例如

(?<=(?<![A-Z])[.!?])\s(?=[A-Z])
于 2012-12-28T02:26:51.687 回答