将文本拆分为句子

Posted

技术标签:

【中文标题】将文本拆分为句子【英文标题】:Split a text into sentences 【发布时间】:2013-04-28 22:48:57 【问题描述】:

如何将文本拆分成句子数组?

示例文本:

给我炒一只海狸。炒我一只海狸!炒我一只海狸? 炒我海狸没有。 4?!给我炸很多海狸...结束

应该输出:

0 => Fry me a Beaver.
1 => Fry me a Beaver!
2 => Fry me a Beaver?
3 => Fry me Beaver no. 4?!
4 => Fry me many Beavers...
5 => End

我尝试了一些通过搜索在 SO 上找到的解决方案,但都失败了,尤其是在第 4 句。

/(?<=[!?.])./

/\.|\?|!/

/((?<=[a-z0-9)][.?!])|(?<=[a-z0-9][.?!]\"))(\s|\r\n)(?=\"?[A-Z])/

/(?<=[.!?]|[.!?][\'"])\s+/    // <- closest one

【问题讨论】:

第 4 句不遵循标准语法。您需要一类Terminators - 标记句子结尾的标记。如果您使用其中一个终止符作为常规符号,那么它要么不是终止符,要么是您误写了句子。简而言之,你不能一边吃蛋糕一边吃。 我一直在做蛋糕吃:P 正则表达式可以像 2 个字符一样向前看,如果第 2 个字符不是大写 A-Z,则表示之前的标点符号无效 听起来你已经知道需要做什么了。 但是我如何将它放入正则表达式? @thelolcat 你最好用你自己的解析器..一个单一的正则表达式是不行的!你必须考虑包含Mr.thelolcatno.1的句子 【参考方案1】:

既然你想“拆分”句子,你为什么要尝试匹配它们?

对于这种情况,让我们使用preg_split()。

代码:

$str = 'Fry me a Beaver. Fry me a Beaver! Fry me a Beaver? Fry me Beaver no. 4?! Fry me many Beavers... End';
$sentences = preg_split('/(?<=[.?!])\s+(?=[a-z])/i', $str);
print_r($sentences);

输出:

Array
(
    [0] => Fry me a Beaver.
    [1] => Fry me a Beaver!
    [2] => Fry me a Beaver?
    [3] => Fry me Beaver no. 4?!
    [4] => Fry me many Beavers...
    [5] => End
)

说明:

简单地说,我们按 分组 空间 \s+ 进行分割并做两件事:

    (?正面看断言后面,基本上我们搜索空格后面是否有点或问号或感叹号。

    (?=[az]) 正向前瞻断言,搜索空格后是否有字母,这是no. 4 问题的一种解决方法。 p>

【讨论】:

只是一个问题:\s 不应该是 \s+ 吗?我的意思是忽略组合在一起的多个空间 谢谢!将它添加到我的助手库 - github.com/Cosmologist/Gears/blob/master/src/Gears/StringType/… @Ryan 快速(?&lt;!\.\.\.)(?&lt;=[.?!]|\.\))\s+(?=[a-z])。看看它是否适合您的需求。 @HamZa Holy Smokes,你太棒了!非常感谢!! 根据我从你那里学到的知识,我能够对其进行编辑以处理我遇到的更多极端情况:regex101.com/r/e4NYyd/4 很酷的东西。

以上是关于将文本拆分为句子的主要内容,如果未能解决你的问题,请参考以下文章

使用正则表达式将字符串拆分为句子

在保留引号的同时使用 nltk 拆分句子

如何使用 REGEX 将作者拆分为对象或数组 C#?

将 pandas df 中的句子拆分为多行单词并对每个句子进行编号

如何将字符串拆分为列表?

如何拆分一列字符串,并从单独的元素创建行? [复制]