2012-08-08 92 views
3

继续我上一个关于preg_split的问题,这个答案超快,谢谢昵称;如果分隔符位于引号内,我真的很希望将场景扩展为不分割字符串。例如:带有两个分隔符的PHP preg_split,除非分隔符在引号内

如果我有串foo = bar AND bar=foo OR foobar="foo bar",我想拆就每一个空间或=字符的刺痛,但包括返回数组中的=字符(目前伟大的作品),但我不希望分割字符串的任何分隔符都在引号内。

我有了这个迄今:

<!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中执行此操作,或者如果还有更好的方法,但是非常感谢您的帮助!

谢谢大家提前!

回答

2

我能够做到这一点,通过添加引用str作为分隔符a-la

"(.*?)"| +|(=) 

被引用的部分将被捕获。看起来这有点脆弱,我没有广泛地测试它,但它至少在你的例子中起作用。

+0

好主意。这应该工作,除非引用的字符串跨越多行。 – 2012-08-08 21:22:06

+0

太棒了,我也添加了单引号检查[''/"(.*?)“|(=)| \'(。*?)\'| + /''] - 这完全符合我所需要的法案。然而,对于寻找类似答案的其他人来说,这种方法会剥去引号,Tim会将它们放在其中。这种方式对我最有效,但Tim的方式也非常特别!谢谢你们俩! – 2012-08-08 21:45:27

+0

@JonathonDavidOates如果你想保持引号只是在引号之外加括号(例如'(“。*?”)')。我以为你的样本数组离开了他们,但我发现它没有。 – 2012-08-08 21:58:39

5

尝试

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

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

部分是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 
) 
+0

不是OP,但试图理解这一点。这个想法是,如果没有偶数个引号字符,那么你现在处于引用段的中间,不应该分裂,对吧? – KRyan 2012-08-08 21:19:11

+1

@DragoonWraith:对。我认为我们并不期望我们的字符串中有任何逃脱的引号。这些也可以用于正则表达式,但我不想让这个过程更加复杂。 – 2012-08-08 21:20:37

+0

非常好,谢谢。非常好;我一直在评论说我不认为RegEx可以处理这个问题。我永远不会想到用偶数引号来确保我们不在引用部分。 – KRyan 2012-08-08 21:21:36

0

但为什么打扰分裂?

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

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

online demo