2016-01-05 40 views
1

我儘量拆分字符串符合下列條件斯普利特周圍字符與正則表達式和條件

  • 將所有字符
  • 斯普利特周圍=如果前面的字符不是%!
  • 斯普利特周圍!=

示例

測試= 45 - > [試驗,= 45]
測試= 45! - > [試驗,= 45!]
測試(%)= 45 - > [試驗(%)= 45]

代碼

private static final Map<String[], String> tests = new HashMap<>(); 

static { 
    tests.put(new String[]{"test", "=", "45"}, "test=45"); 
    tests.put(new String[]{"test", "!=", "45"}, "test!=45"); 
    tests.put(new String[]{"test%=45"}, "test%=45"); 
    tests.put(new String[]{"test", "=", "%=45"}, "test=%=45"); 
    tests.put(new String[]{"test%=", "=", "%=45"}, "test%==%=45"); 
} 

@org.junit.Test 
public void simpleTest() { 
    String regex = "(?=!=)|(?<=!=)|(?<![!%])((?<==)|(?==))"; 
    for (Map.Entry<String[], String> entry : tests.entrySet()) { 
     Assert.assertArrayEquals(entry.getKey(), entry.getValue().split(regex)); 
    } 
} 

「最好」的事情,我發現是(?=!=)|(?<=!=)|(?<![!%])((?<==)|(?==))但我不知道爲什麼%=它拆分後((?<==)似乎是EXECUT ed)
左右字符可以是任何ACII表。

結果

測試= 45 - > [試驗,= 45]
測試= 45 - > [試驗,= 45!]
測試(%)= 45 - >! [測試(%)= 45] < - 應該[試驗(%)= 45]
測試=(%)= 45 - > [試驗,= %= 45] < - 應該[試驗,=,% = 45]
test%==%= 45 - > [test%=,=,(%)= 45] < - 應該[試驗(%)=,=,(%)= 45]

是否有可能與一個正則表達式和分割做呢?

注意:這是正則表達式的只是一部分,它是用來「輕鬆」解析數據,所以是的,我可以用簡單的代碼來執行它,而不是使用正則表達式和分裂的,但是這不是我什麼要求。

回答

1

您需要的回顧後移入lookarounds檢查等號存在:

(?<=!=)|(?=!=)|((?<=(?<![!%])=)|(?=(?<![!%])=)) 

this demo

我修改這一部分:((?<=(?<![!%])=)|(?=(?<![!%])=))

( 
(?<=(?<![!%])=) - matches a location preceded by a = sign that is not preceded with ! or % 
| 
(?=(?<![!%])=) - matches a location followed by a = sign that is not preceded with ! or % 
) 
+0

我不知道爲什麼我還沒有想過這個問題。非常感謝 – Duffydake

+0

通常情況下,嵌套週轉不是一個好主意,所以它確實是可以輕易跳過我們的注意力的東西。在這裏,不需要檢查轉義的實體,因此可以使用它們。 –

+0

圍繞第3部分和第4部分的額外括號是無關緊要的。另外,爲什麼在第1部分中明確包含'!='之後的匹配時在第3部分中的*'!='之後排除匹配*?刪除第1部分並將第3部分更改爲僅排除'%='。 – Andreas

1

您可以使用正則表達式這樣

(?=!=|(?<![!%])=)|(?<=!=|(?<![!%])=) 

提取的核心節重複先行和回顧後段:

String core = "!=|(?<![!%])="; 
String regex = "(?=" + core + ")|(?<=" + core + ")"; 

Regex101 DemoIdeone Demo

正則表達式突圍核心只有

!=   # A literal '!=' 
    |   # OR 
    (?<![!%])= # A literal '=' that is not preceded by '!' or '%'