将PHP中的一个段落分解为句子

15

我一直在使用

explode(".",$mystring)

将段落拆分为句子。但是,这并不包括以不同标点符号结尾的句子,例如! ?:;

是否有一种方法可以使用数组作为分隔符,而不是单个字符?或者是否有其他巧妙的方法可以使用各种标点符号进行拆分?

我尝试过了

要将一个段落拆分成句子,但是无法涵盖以不同标点符号结尾的句子,例如!?:;是否有一种使用数组作为分隔符的方法?或者是否有其他巧妙的方法可以使用各种标点符号进行拆分?

我已经尝试过了。

explode(("." || "?" || "!"),$mystring)

希望可以,但实际上没有成功...


使用正则表达式来匹配模式并将值存储在变量中,然后将该变量作为参数传递给explode函数。 - sree
请查看https://dev59.com/1m445IYBdhLWcg3wGmk6。 - Boby
8个回答

24
您可以使用preg_split()PCRE前瞻条件结合,以在保留实际标点符号的同时,在每个出现.;:?!、..后分割字符串:

代码:

$subject = 'abc sdfs.    def ghi; this is an.email@addre.ss! asdasdasd? abc xyz';
// split on whitespace between sentences preceded by a punctuation mark
$result = preg_split('/(?<=[.?!;:])\s+/', $subject, -1, PREG_SPLIT_NO_EMPTY);
print_r($result);

结果:

Array
(
    [0] => abc sdfs.
    [1] => def ghi;
    [2] => this is an.email@addre.ss!
    [3] => asdasdasd?
    [4] => abc xyz
)

你还可以添加缩写黑名单(如Mr.,Mrs.,Dr.等),这些缩写不应该被分割成独立的句子,通过插入负回顾断言来实现:

$subject = 'abc sdfs.   Dr. Foo said he is not a sentence; asdasdasd? abc xyz';
// split on whitespace between sentences preceded by a punctuation mark
$result = preg_split('/(?<!Mr.|Mrs.|Dr.)(?<=[.?!;:])\s+/', $subject, -1, PREG_SPLIT_NO_EMPTY);
print_r($result);

结果:

Array
(
    [0] => abc sdfs.
    [1] => Dr. Foo said he is not a sentence;
    [2] => asdasdasd?
    [3] => abc xyz
)

这对我帮助很大。如果句子以数字结尾,比如:“这是我的测试40。但也有新的。” - FosAvance

6

您可以做到:

preg_split('/\.|\?|!/',$mystring);

或者(更简单):
preg_split('/[.?!]/',$mystring);

1
该方法从最终字符串中删除句号等符号。 - 472084
1
好的解决方案,但如果句子中有“Smith先生”,它就不起作用。 - Victor Stoddard
@VictorStoddard 说句闲话,我在我的答案中解决了这个问题。 - Kaii

4
假设您确实需要最终结果包含标点符号,您是否尝试过以下方法:
 $mystring = str_replace("?","?---",str_replace(".",".---",str_replace("!","!---",$mystring)));
 $tmp = explode("---",$mystring);

这将使您的标点符号保持原样。

1
preg_split('/\s+|[.?!]/',$string);

可能的问题是,如果有一个电子邮件地址,它可能会在中途将其拆分成新的一行。

0

使用explode函数时不能有多个分隔符。这就是preg_split();的作用。但即使如此,它也只会在分隔符处分割,因此返回的句子将没有标点符号。 您可以进一步使用preg_split并使用PREG_SPLIT_DELIM_CAPTURE标志将它们返回到自己的元素中,然后运行一些循环来将句子和后面的标点符号合并到返回的数组中,或者只需使用preg_match_all();

preg_match_all('~.*?[?.!]~s', $string, $sentences);

0
你可以尝试使用 preg_split
$sentences = preg_split("/[.?!:;]+/", $mystring);

请注意,这将删除标点符号。如果您还想去除前导或尾随空格,请执行相应操作。
$sentences = preg_split("/[.?!:;]+\s+?/", $mystring);

0
使用 preg_split 并给它一个像 [\.|\?!] 的正则表达式来分割。

0
$mylist = preg_split("/[.?!:;]/", $mystring);

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