如何将句子分成单词和标点符号?

时间:2013-04-22 00:07:13

标签: php regex string preg-split text-segmentation

例如,我想拆分这句话:

I am a sentence.

成5个部分的阵列; Iamasentence.

我在尝试preg_split后正在使用explode,但我似乎无法找到合适的内容。

这是我尝试过的:

$sentence = explode(" ", $sentence);
/*
returns array(4) {
  [0]=>
  string(1) "I"
  [1]=>
  string(2) "am"
  [2]=>
  string(1) "a"
  [3]=>
  string(8) "sentence."
}
*/

还有这个:

$sentence = preg_split("/[.?!\s]/", $sentence);
/*
returns array(5) {
  [0]=>
  string(1) "I"
  [1]=>
  string(2) "am"
  [2]=>
  string(1) "a"
  [3]=>
  string(8) "sentence"
  [4]=>
  string(0) ""
}
*/

如何做到这一点?

3 个答案:

答案 0 :(得分:5)

您可以拆分字边界:

$sentence = preg_split("/(?<=\w)\b\s*/", 'I am a sentence.');

几乎正则表达式扫描直到找到一个单词字符,然后在它之后,正则表达式必须捕获一个单词边界和一些可选空格。

Output

array(5) {
  [0]=>
  string(1) "I"
  [1]=>
  string(2) "am"
  [2]=>
  string(1) "a"
  [3]=>
  string(8) "sentence"
  [4]=>
  string(1) "."
}

答案 1 :(得分:3)

我正在寻找相同的解决方案并降落在这里。已接受的解决方案不适用于撇号和重音符号等非单词字符。下面,找到适合我的解决方案。

这是我的测试句子:

  克莱尔最喜欢的钢琴奏鸣曲是莫扎特的奏鸣曲号码。 C大调15。

接受的答案给了我以下结果:

Array
(
    [0] => Claire
    [1] => ’s
    [2] => favorite
    [3] => sonata
    [4] => for
    [5] => piano
    [6] => is
    [7] => Mozart
    [8] => ’s
    [9] => Sonata
    [10] => no
    [11] => . 15
    [12] => in
    [13] => C
    [14] => Major
    [15] => .
)

我想出的解决方案如下:

$parts = preg_split("/\s+|\b(?=[!\?\.])(?!\.\s+)/", $sentence);

它给出了以下结果:

Array
(
    [0] => Claire’s
    [1] => favorite
    [2] => sonata
    [3] => for
    [4] => piano
    [5] => is
    [6] => Mozart’s
    [7] => Sonata
    [8] => no.
    [9] => 15
    [10] => in
    [11] => C
    [12] => Major
    [13] => .
)

答案 2 :(得分:0)

如果有人对忽略标点符号的简单解决方案感兴趣

preg_split( '/[^a-zA-Z0-9]+/', 'I am a sentence' );

将分为

array(4) {
  [0]=>
  string(1) "I"
  [1]=>
  string(2) "am"
  [2]=>
  string(1) "a"
  [3]=>
  string(8) "sentence"
}

或者在相邻单词中包含标点符号的替代解决方案

preg_split( '/\b[^a-zA-Z0-9]+\b/', 'I am a sentence.' );

将分为

array(4) {
  [0]=>
  string(1) "I"
  [1]=>
  string(2) "am"
  [2]=>
  string(1) "a"
  [3]=>
  string(8) "sentence."
}