使用正则表达式和PHP将段落分成句子

12

我是一个正则表达式新手,正在尝试将段落分割为句子。在我的语言中,我们在句子中使用了相当多的缩写词(例如:bl.a.),因此我得出的结论是,我需要寻找紧跟着一个单空格和以大写字母开头的单词的标点符号,像这样:

[sentence1]...anymore. However...[sentence2]

因此,像这样的段落:

Der er en lang og bevæget forhistorie bag lov om varsling m.v. i forbindelse med afskedigelser af større omfang. Det er ikke en bureaukratisk lovtekst blandt så mange andre.

应该以这个输出结束:

[0] => Der er en lang og bevæget forhistorie bag lov om varsling m.v. i forbindelse med afskedigelser af større omfang.
[1] => Det er ikke en bureaukratisk lovtekst blandt så mange andre.

而不是这个:

[0] => Der er en lang og bevæget forhistorie bag lov om varsling m.v. 
[1] => i forbindelse med afskedigelser af større omfang.
[2] => Det er ikke en bureaukratisk lovtekst blandt så mange andre.

我已经找到了一种解决方案,可以通过正向后顾特性来完成第一部分:

$regexp = (?<=[.!?] | [.!?][\'"]);

然后

$sentences = preg_split($regexp, $paragraph, -1, PREG_SPLIT_NO_EMPTY);

这是一个很好的起点,但由于缩写词过多,切分太频繁。

我尝试做了这个:

(?<=[.!?]\s[A-Z] | [.!?][\'"])

以便针对任何一个出现的情况进行定位

. or ! or ?

后面跟一个空格和一个大写字母,但是并没有起作用。

有人知道是否有办法实现我想做的事情吗?


不一定,我对 preg_split PHP 函数的输出格式非常满意。我遇到的问题是编写正则表达式以查找“ This. Is”条件。 - acrmuui
嗨Ka,我已经更新了问题,并提供了我所寻找的输出示例。 - acrmuui
2
@ka:不,这个问题不是链接问题的重复。 - Madara's Ghost
通过你正在使用的正则表达式,我看到你需要/想要支持引号["'],你还需要吗?你能提供一个想要按引号拆分的示例和一个不想要的示例吗? - CSᵠ
1
@acrmuui 是的,看起来不错,但你在发布的示例中没有引号使用。 - CSᵠ
显示剩余3条评论
2个回答

16

这里的“Unicode”是具有误导性的。此正则表达式确实使用了Unicode字符属性,但它实现由UAX 29定义的Unicode句子边界规则。 - NikiC
@NikiC,确实不是百分之百可靠的,但UAX29也指出:*...实现可以自由地覆盖(定制)结果以满足要求...* - CSᵠ
1
虽然不适用于“例如”和“第二个文本”,但它不应该在此处拆分。 - tjvg1991
@tjvg1991 确实,这只是一个通用解决方案,您可以在正则表达式上添加那些特殊情况。 - CSᵠ

3

寻找这样的模式仍然似乎不可靠,但由于句子可能会以换行符结束,我会尝试仅使用以下内容进行搜索。

[.\!\?][\s\n\r\t][A-Z] 

我认为你实际上不需要提到look-ahead(向前查找),因为使用 !? (将其连写,所以使用 \ 转义它 - 告诉正则表达式忽略任何特殊含义)。


@ka 理论上它包含两者,但实际上我发现使用不同的Java/PHP版本/方法会得到不同的结果。 - Nick Cardoso

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接