PHP preg_split有两个分隔符,除非分隔符在引号内

时间:2012-08-08 21:10:51

标签: php regex delimiter preg-split

从我之前关于preg_split的问题开始,这个答案超级快,这要归功于尼克;当分隔符在引号内时,我真的想将场景扩展为不拆分字符串。例如:

如果我有字符串foo = bar AND bar=foo OR foobar="foo bar",我希望在每个空格或=字符上拆分sting,但在返回的数组中包含=字符(当前效果很好) ),但我不想拆分字符串中的任何一个分隔符都在引号内。

到目前为止我已经得到了这个:

<!doctype html>
<?php

$string = 'foo = bar AND bar=foo';

$array = preg_split('/ +|(=)/', $string, -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY);

?>
<pre>
<?php

print_r($array);

?>
</pre>

哪个让我:

Array
(
    [0] => foo
    [1] => =
    [2] => bar
    [3] => AND
    [4] => bar
    [5] => =
    [6] => foo
)

但如果我将字符串更改为:

$string = 'foo = bar AND bar=foo OR foobar = "foo bar"';

我真的很喜欢这个数组:

Array
(
    [0] => foo
    [1] => =
    [2] => bar
    [3] => AND
    [4] => bar
    [5] => =
    [6] => foo
    [6] => OR
    [6] => foobar
    [6] => =
    [6] => "foo bar"
)

请注意"foo bar"没有在空格上拆分,因为它在引号中?

真的不确定如何在RegEx中执行此操作,或者是否有更好的方法,但我非常感谢您的所有帮助!

提前谢谢大家!

3 个答案:

答案 0 :(得分:5)

尝试

$array = preg_split('/(?: +|(=))(?=(?:[^"]*"[^"]*")*[^"]*$)/', $string, -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY);

(?=(?:[^"]*"[^"]*")*[^"]*$)

part是lookahead assertion,确保字符串前面有偶数个引号字符,因此如果当前位置在引号之间,它将失败:

(?=      # Assert that the following can be matched:
 (?:     # A group containing...
  [^"]*" #  any number of non-quote characters followed by one quote
  [^"]*" #  the same (to ensure an even number of quotes)
 )*      # ...repeated zero or more times,
 [^"]*   # followed by any number of non-quotes
 $       # until the end of the string
)

答案 1 :(得分:2)

我能够通过添加带引号的字符串作为分隔符a-la

来完成此操作
"(.*?)"| +|(=)

将引用引用的部分。这似乎有点脆弱,我没有广泛测试它,但它至少适用于你的例子。

答案 2 :(得分:0)

但为什么还要分手?

在查看这个旧问题之后,我会想到这个简单的解决方案,使用的是preg_match_all而不是preg_split。我们可以使用这个简单的正则表达式来指定我们想要的东西:

"[^"]*"|\b\w+\b|=

请参阅online demo