2010-01-20 58 views
5

我使用php的preg_split分割基於分號的字符串,但我需要它只分裂在非轉義的分號。正則表達式分裂所有未轉義的分號

<? 
$str = "abc;def\\;abc;def"; 
$arr = preg_split("/;/", $str); 
print_r($arr); 
?> 

產地:

Array 
(
    [0] => abc 
    [1] => def\ 
    [2] => abc 
    [3] => def 
) 

當我希望它產生:

Array 
(
    [0] => abc 
    [1] => def\;abc 
    [2] => def 
) 

我已經試過"/(^\\)?;/""/[^\\]?;/"但他們都產生錯誤。有任何想法嗎?

+1

@Corey,如果你不想在最終輸出中使用分號,爲什麼還要逃脫分號? – 2010-01-20 08:24:05

+0

@Doug錯字,在最終輸出中添加了分號 – 2010-01-20 08:34:06

+0

逃生逃脫了嗎?換句話說,字符串文字是否可以像這樣:''abc; def \\\\; abc; def「'(split into:[abc,def \\,abc,def'])? – 2010-01-20 11:51:39

回答

5

這工作。

<? 
    $str = "abc;def\;abc;def"; 
    $arr = preg_split('/(?<!\\\);/', $str); 
    print_r($arr); 
?> 

它輸出:

Array 
(
    [0] => abc 
    [1] => def\;abc 
    [2] => def 
) 

你需要利用負回顧後(read about lookarounds)的。想想「全部匹配」;「除非以「\」開頭。

+0

感謝您的鏈接! – 2010-01-20 08:34:34

+0

這將工作,除非你有一個以反斜槓結尾的元素 - 無法轉義該反斜槓,因爲對於正則表達式,它看起來像是在轉義分號。 – Ariel 2012-03-29 01:34:23

2

我與PHP的正則表達式沒有真正精通,但試試這個:

/(?<!\\);/ 
+0

它需要三重'\'。這裏僅使用2個產生的錯誤。不知道爲什麼這樣。 – 2010-01-20 08:26:38

+0

您的答案適用於三重'\',但Nils在解釋原因時採取了額外步驟。儘管努力獲得+1! – 2010-01-20 08:32:27

0

既然Bart問道:當然你也可以使用正則表達式來分割未轉義的;並考慮到逃脫轉義字符。它只是變得有點凌亂:

<? 
    $str = "abc;def\;abc\\\\;def"; 
    preg_match_all('/((?:[^\\\\;]|\\\.)*)(?:;|$)/', $str, $arr); 
    print_r($arr); 
?> 

Array 
(
    [0] => Array 
     (
      [0] => abc; 
      [1] => def\;abc\\; 
      [2] => def 
    ) 

    [1] => Array 
     (
      [0] => abc 
      [1] => def\;abc\\ 
      [2] => def 
    ) 
) 

這樣做是要爲正則表達式「(任何字符除了\和;)或(\後跟任意字符)」,並允許任意數量的,其次由;或字符串的結尾。

我不知道PHP如何處理字符串中的$和行尾字符,您可能需要設置一些正則表達式選項以獲得您想要的值。