【发布时间】:2017-02-04 15:00:14
【问题描述】:
正则表达式:
(?:(?:Jr|Master|Mr|Ms|Mrs|Dr|Capt|Col|Sgt|Sr|Prof|Rep|Mt|Mount|St|Etc|Eg)\.\s+|["'“(\[]?)(?:\b(?:(?!(?:\S{1,})[.?!]+["']?\s+["']?[A-Z]).)*)(?:(?:(?:Jr|Master|Mr|Ms|Mrs|Dr|Capt|Col|Sgt|Sr|Prof|Rep|Mt|Mount|St|Etc|Eg)\.\s+(?:(?!\w{2,}[.?!]['"]?\s+["']?[A-Z]).)*)?)*(?:(?![.?!]["']?\s+["']?\w).)*(?:[.?!)\]]+["'”]?|[^\r\n]+$)
可以看到一个regex101 here。
可视化节点图:https://regexper.com(输入正则表达式字符串)
这个正则表达式来自一个 Sitepoint 讨论,with an explanation here。
目标:不仅通过 .?! 匹配句子,而且确定何时这样做,例如在引号之外,但也不用缩写打断句子。
主要问题:
有一个主要问题,像下面这样的字符串在不应该的情况下在中间用句号分开 - 我需要引号保持完整。
问题:“这是个问题。你听到了吗?”
除此之外,这个正则表达式是否最可靠、最有效?
可能还有其他两个可能的问题,或“异常”(参见上面的 regex101):
可能的问题/例外句(由于“先生”而没有正确拆分): 2 月 20 日,X 先生说“在第四面墙之外,应该有‘光’”?!......或者什么的。第二句。第三。
和
可能的问题/异常(“真的吗?”不应该在大写名称之前分开?:“真的吗?”贝克先生一边思考一边问道。
我在打开此主题时遇到的以前的问题,我已修复,是:
在一个字母后跟一个带有句号的标点符号之后,一个新句子之前,文本没有拆分。 (例如。A.S.A.P!新行。)
引用后出现句号时文本没有拆分。
句子开头的缩写会中断。 (例如,蒂莫西中士。)
不匹配没有结束标点的新行。
你觉得这个实现怎么样?谢谢!
【问题讨论】:
-
对于任何正则表达式的工作,句子需要始终遵循预设数量的规则(您必须确定)。一个规则可能是这样的:一个句子总是有一个“。”在末尾。如果句子是由人类创建的,并且没有经过规则验证,那么您将永远无法找到有效的正则表达式模式。
-
一个重要的预设规则是:缩写不能有空格,必须以大写字母开头。
-
正如你所说,人类创造的句子的正则表达式。我理解这条规则,但是我更喜欢对错误或奇怪的情况不区分大小写。我知道我在自然语言处理之前扩展了这一点。
-
如果新行是句子终止符,请将其添加到规则旁边
.!? -
@user1679669 我会尝试像
((["'])(?:[^\\]|\\[\s\S])*?\2)这样匹配引号,其中有效的引号字符是"和'(尽管您可能需要不同的引号字符来避免 foo's 被视为报价开始)。re.exec('abc "def\' gh\\"i " jkl'); // [""def' gh\"i "", ""def' gh\"i "", """]。这是来自引号的代码概念。因此,根据您的情况进行调整
标签: javascript regex string split match