从我之前关于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中执行此操作,或者是否有更好的方法,但我非常感谢您的所有帮助!
提前谢谢大家!
答案 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。