2010-10-06 43 views
9

字符串字符串被拆分拆分有逃避使用正則表達式序列中的Java

abc:def:ghi\:klm:nop 

字符串應該基於分裂「:」 「\」是轉義字符。所以「\:」不應該被視爲標記。

拆分( 「:」)給出

[abc] 
[def] 
[ghi\] 
[klm] 
[nop] 

要求輸出字符串數組

[abc] 
[def] 
[ghi\:klm] 
[nop] 

如何才能\:被忽略

+0

下面是可能的:'abc:「def:ghi」:jkl'? – 2010-10-06 09:35:14

回答

16

使用look-behind assertion

split("(?<!\\\\):") 

只有在前面沒有\時纔會匹配。使用雙轉義\\\\是必需的,因爲需要一個字符串聲明和一個正則表達式。

但請注意,如果您希望允許令牌以反斜槓結尾,則不會允許您轉義反斜槓。要做到這一點,你必須先與

string.replaceAll("\\\\\\\\", ESCAPE_BACKSLASH) 

(其中ESCAPE_BACKSLASH是不會在你輸入發生字符串),然後使用向後看斷言替換所有雙反斜線,拆分後,更換ESCAPE_BACKSLASH串與

token.replaceAll(ESCAPE_BACKSLASH, "\\\\") 
0

濃湯是正確使用look-behind assertion,但如果你的字符串包含轉義轉義字符(如\\)就在逗號前在反斜槓,分流可能打破。看到這個例子:

test1\,test1,test2\\,test3\\\,test3\\\\,test4

如果你做(?<!\\),作爲濃湯提出了一個簡單的外觀,背後分拆後,字符串被分成兩個部分,只有test1\,test1test2\\,test3\\\,test3\\\\,test4。這是因爲後視僅檢查一個字符返回換碼字符。如果字符串在逗號和逗號之前以偶數個轉義字符開頭,那麼實際上是正確的。

要做到這一點稍微複雜的(雙)查找背後需要表達:

(?<!(?<![^\\]\\(?:\\{2}){0,10})\\),

在Java中使用這種更復雜的正則表達式,再次要求所有\通過\\逃跑。因此,這應該是一個更復雜的回答你的問題:

"any comma separated string".split("(?<!(?<![^\\\\]\\\\(?:\\\\{2}){0,10})\\\\),"); 

注: Java不支持lookbehinds內無限次重複。因此,只能使用表達式{0,10}檢查最多10個重複雙轉義字符。如果需要,您可以通過調整後面的數字來增加此值。