PHP preg_split 将特殊字符放在双引号内

PHP preg_split keep special characters inside double quotemarks

我在 preg_split 中使用正则表达式将字符串拆分成单独的部分。

$string = 'text required name="first_name" label="First Name" column="1/2"';
$ps = preg_split("/\s(?![\w\s]+\")/u", $string);
echo '<pre>',print_r($ps,1),'</pre>';

以上代码给出了以下结果并且工作正常:

Array
(
[0] => text
[1] => required
[2] => name="first_name"
[3] => label="First Name"
[4] => column="1/2"
)

但是如果我在双引号内添加任何特殊字符,字符串将被分解为单独的数组项:

$string = 'text required name="first_name" label="First Name! $ , ." column="1/2"';
$ps = preg_split("/\s(?![\w\s]+\")/u", $string);
echo '<pre>',print_r($ps,1),'</pre>';

导致:

Array
(
[0] => text
[1] => required
[2] => name="first_name"
[3] => label="First
[4] => Name!
[5] => $
[6] => ,
[7] => ."
[8] => column="1/2"
)

如何保留“名字!$ , .”在同一个数组项中?

例如像这样:

Array
(
[0] => text
[1] => required
[2] => name="first_name"
[3] => label="First Name! $ , ."
[4] => column="1/2"
)

我会在这里使用 preg_match_all 并进行以下交替:

\w+=\".*?\"|\b\w+(?!\S)

此模式将尝试匹配 key="value" 条目。如果失败,它将尝试匹配一个独立的单词,该单词后跟空格或者是输入中的最后一个单词。

PHP代码:

$input = 'text required name="first_name" label="First Name! $ , ." column="1/2"';
preg_match_all("/\w+=\".*?\"|\b\w+(?!\S)/", $input, $matches);
print_r($matches);

这会打印:

Array
(
    [0] => text
    [1] => required
    [2] => name="first_name"
    [3] => label="First Name! $ , ."
    [4] => column="1/2"
)

您可以使用此正则表达式进行拆分:

"[^"\]*(?:\.[^"\]*)*"(*SKIP)(*F)|\h+

代码:

php > $string = 'text required name="first_name" label="First Name! \"$ , ." column="1/2"';
php > $re = '/"[^"\\]*(?:\\.[^"\\]*)*"(*SKIP)(*F)|\h+/';
php > print_r( preg_split($re, $string) );
Array
(
    [0] => text
    [1] => required
    [2] => name="first_name"
    [3] => label="First Name! \"$ , ."
    [4] => column="1/2"
)

RegEx Demo

正则表达式解释:

  • "[^"\]*(?:\.[^"\]*)*":匹配可能包含转义字符的引号字符串
  • (*SKIP)(*F):跳过本场比赛并失败
  • |: 或
  • \h+: 匹配 1+ 个空格