2012-08-08 85 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