在unicode模式下preg_split:delim_capture不工作?

时间:2012-02-02 14:36:51

标签: php regex unicode

我正在尝试使用正则表达式将一大块中文文本拆分成句子。为了我的目的,句子分隔符是:

  • 全宽句号。(0x3002)
  • 全角问号?(0xFF1F)
  • 全宽感叹号!(0xFF01)

现在,让我们说我的$ str是这样的: $str = "你好。你好吗? 我是程序员,不太懂这个我问题,希望大家能够帮忙!一起加油吧!";

我使用带有这些参数的preg_split:

$str2 = preg_split("/([\x{3002}\x{FF01}\x{FF1F}])/u",$str,PREG_SPLIT_DELIM_CAPTURE|PREG_SPLIT_NO_EMPTY);

$ str2现在是一个如下所示的数组:

array(3) { [0]=> string(6) "你好" [1]=> string(9) "你好吗" [2]=> string(91) " 我是程序员,不太懂这个我问题,希望大家能够帮忙!一起加油吧!" }

但是,预期的输出是:

[0] "你好。" 
[1] "你好吗?"
[2] "我是程序员,不太懂这个我问题,希望大家能够帮忙!"
[3] "一起加油吧!"

正如您所看到的,有两个问题:这不能正确处理感叹号,其次,我的全宽全停和全宽问号消失。我希望delim_capture能够保留它们。我一直在看这段代码这么长时间我不可能弄清楚问题是什么了。我非常感谢建议。

2 个答案:

答案 0 :(得分:4)

你的正则表达式代码应该像这样能够捕获字符串+分隔符:

$str = "你好。你好吗? 我是程序员,不太懂这个我问题,希望大家能够帮忙!一起加油吧!";
$arr = preg_split("/\s*([^\x{3002}\x{FF01}\x{FF1F}]+[\x{3002}\x{FF01}\x{FF1F}]\s*)/u",
                  $str, 0, PREG_SPLIT_DELIM_CAPTURE|PREG_SPLIT_NO_EMPTY );
var_dump($arr);

<强>输出:

 array(4) {
  [0]=> string(9)  "你好。"
  [1]=> string(13) "你好吗? "
  [2]=> string(72) "我是程序员,不太懂这个我问题,希望大家能够帮忙!"
  [3]=> string(18) "一起加油吧!"
}

答案 1 :(得分:3)

您错过了preg_split()$limit参数。

  

array preg_split(string $ pattern,string $ subject [,int $ limit = -1 [,int $ flags = 0]])

因此,您将PREG_SPLIT_DELIM_CAPTURE(2)+ PREG_SPLIT_NO_EMPTY(1)= 3作为$limit传递。这就是为什么它会在三点停止。

添加null作为$limit参数,您的状态良好。

preg_split($pattern, $str, null, PREG_SPLIT_DELIM_CAPTURE|PREG_SPLIT_NO_EMPTY)