我有这个正则表达式:(?<![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.史密斯”呢?从逻辑上讲,它应该......
我希望它在字符串中检测到这个结构:
没有大写字母+句号/?/!+空格+大写字母
答案 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]
。“也许你的意思是嵌套它们,例如
[.!?]