Regex (preg_split):如何基于分隔符进行分割,不包括括在一对引号中的分隔符


Regex (preg_split): how do I split based on a delimiter, excluding delimiters included in a pair of quotes?

我分割了这个:

1 2 3 4/5/6 "7/8 9" 10

这:

1
2
3
4
5
6
"7/8 9"
10
与preg_split ()

那么我的问题是,如何根据分隔符进行分割,不包括一对引号内的分隔符?

我有点想避免首先捕获引号中的内容,理想情况下希望它是一行。

您可以使用以下命令:

$text = '1 2 3 4/5/6 "7/8 9" 10';
$results = preg_split('~"[^"]*"(*SKIP)(*F)|[ /]+~', $text);
print_r($results);

:

在替换操作符的左侧,我们匹配引号中的任何内容,使子模式失败,强制正则表达式引擎不使用回溯控制(*SKIP)(*F)来重试子字符串。交替操作符的右侧匹配空格字符或不在引号内的正斜杠。

Array
(
    [0] => 1
    [1] => 2
    [2] => 3
    [3] => 4
    [4] => 5
    [5] => 6
    [6] => "7/8 9"
    [7] => 10
 )

您可以使用:

$s = '1 2 3 4/5/6 "7/8 9" 10';
$arr = preg_split('~("[^"]*")|[ /]+~', $s, -1, PREG_SPLIT_DELIM_CAPTURE|PREG_SPLIT_NO_EMPTY);
print_r( $arr );
输出:

Array
(
    [0] => 1
    [1] => 2
    [2] => 3
    [3] => 4
    [4] => 5
    [5] => 6
    [6] => "7/8 9"
    [7] => 10
)

另一种使用可选组的方式:

$arr = preg_split('~(?:"[^"]*")?'K[/'s]+~', $s);

模式"[^"]*"[/'s]+匹配带引号的部分,后面跟着一个或多个空格和斜杠。但是由于您不想删除引用部分,因此在其后面加上'K'K从匹配结果中删除左侧所有匹配的内容。使用此技巧,当找到引号部分时,regex引擎只返回后面的空格或斜杠,并对它们进行分割。

由于空格或斜杠之前并不总是有引号部分,因此您只需要使用非捕获组(?:...)和问号?

使其成为可选的。