带有多个模式的preg_split()不会拆分带引号的字符串

时间:2018-09-28 08:08:31

标签: php regex string split string-parsing

我需要将一段分为句子。 那就是我对正则表达式感到困惑的地方。

我已经将此Q标记为与之重复的question。但是这里的问题有所不同。

以下是我需要拆分的字符串的示例:

  

你好!你好吗?生活怎么样
  过着自由的生活。 “不是吗?”

这是我尝试的代码:

$sentence_array = preg_split('/([.!?\r\n|\r|\n])+(?![^"]*")/', $paragraph, -1);

我需要的是:

array (  
  [0] => "hello"  
  [1] => "how are you"  
  [2] => "how is life"  
  [3] => "live life, live free"  
  [4] => ""isnt it?""  
)

我得到的是:

array(
  [0] => "hello! how are you? how is life live life, live free. "isnt it?""
)

当字符串中没有引号时,拆分将按要求进行。

感谢您的帮助。谢谢。

2 个答案:

答案 0 :(得分:2)

您的正则表达式存在一些问题,即它们的主要问题是使组构造与字符类混淆。字符类中的管道df = left_df.join(right_df, left.name == right.name) 的字面意思是|。它没有任何特殊含义。

您需要的是这个

|

这首先尝试匹配用双引号引起来的字符串(并捕获内容)。然后尝试匹配("[^"]*")|[!?.]+\s*|\R+ 中设置为在其上拆分的所有标点符号。然后找到任何换行符。

PHP:

[!?.]

输出:

var_dump(preg_split('~("[^"]*")|[!?.]+\s*|\R+~', <<<STR
hello! how are you? how is life
live life, live free. "isnt it?"
STR
, -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY));

答案 1 :(得分:1)

我查看您基于已解决的某些标点符号进行拆分的问题,除了在双引号的情况下无法解决的问题。我们可以说一个解决方案,说在看到这种标点符号时应该拆分,在看到这种标点符号后加上双引号的情况下应该

当前一个字符与您的一个标记相匹配时,应该发生拆分,否则后面的内容不是双引号,或者前两个字符应为标记双引号。这意味着使用以下模式进行拆分:

(?<=[.!?\r\n])(?=[^"])|(?<=[.!?\r\n]")(?=.)

代码示例:

$input = "hello! how \"are\" \"you?\" how is life\nlive life, live free. \"isnt it?\"";
$sentence_array = preg_split('/(?<=[.!?\r\n])(?=[^"])|(?<=[.!?\r\n]\")(?=.)/', $input, -1);
print_r($sentence_array);

Array ( [0] => hello! [1] => how "are" "you?" [2] => how is life
    [3] => live life, live free. [4] => "isnt it?" )