2012-02-07 43 views
5

是否可以減去字符類中的匹配字符?模式:如何減少字符類中的匹配字符?

Java docs都具有約字符類的例子與減法:

[a-z&&[^bc]] - a through z, except for b and c: [ad-z] (subtraction) 
[a-z&&[^m-p]] - a through z, and not m through p: [a-lq-z](subtraction) 

我想要寫圖案,該圖案匹配兩個雙字字符,當對不是相同的:

1) "aaaa123" - should NOT match 
2) "aabb123" - should match "aabb" part 
3) "aa--123" - should NOT match 

我用以下模式接近成功:

([\w])\1([\w])\2 

,但當然它不適用於情況1,所以我需要減去第一組的匹配。但是,當我嘗試這樣做:

Pattern p = Pattern.compile("([\\w])\\1([\\w&&[^\\1]])\\2"); 

我得到一個異常:

Exception in thread "main" java.util.regex.PatternSyntaxException: Illegal/unsupported escape sequence near index 17 
([\w])\1([\w&&[^\1]])\2 
       ^
    at java.util.regex.Pattern.error(Pattern.java:1713) 

如此看來它不與團體工作,但只是列出具體的字符。以下模式編譯沒有問題:

Pattern p = Pattern.compile("([\\w])\\1([\\w&&[^a]])\\2"); 

是否有任何其他方式來編寫此類模式?

回答

3

使用

Pattern p = Pattern.compile("((\\w)\\2(?!\\2))((\\w)\\4)"); 

你的角色會進入組13

這可以通過使用負向預測來確保第一個字符組中第二個字符後面的字符是不同的字符。

1

您正在使用錯誤的工具進行工作。盡一切辦法使用正則表達式來檢測字符對對,但您可以使用!=來測試對中的字符是否相同。嚴重的是,沒有理由在正則表達式中使用的所有內容 - 它會導致無法讀取,不可移植的代碼,並且除了「看起來很酷」之外,沒有其他好處。

+1

正則表達式確實讓一個看起來很酷:HTTP:// XKCD。com @ 208 @ – flesk 2012-02-07 10:03:15

+0

@Kilian:這個模式只是用於匹配字符串部分的許多(也有很多簡單的)模式之一 - 所以這不僅僅是因爲你說的「酷」 - 系統遍歷模式並匹配它們。 ..如果我會用你建議的方式去 - 我會讓它更「不冷酷」的解決方案,因爲我需要爲一個或另一個案例添加自定義的'ifs' ... – Laimoncijus 2012-02-07 10:03:34

+0

@flesk:非常好,從我+1 ! :) – Laimoncijus 2012-02-07 10:04:38

1

嘗試此

String regex = "(\\w)\\1(?!\\1)(\\w)\\2"; 
Pattern pattern = Pattern.compile(regex); 

(?!\\1)negative lookahead,它確保的\\1內容不被以下

我的測試碼

String s1 = "aaaa123"; 
String s2 = "aabb123"; 
String s3 = "aa--123"; 
String s4 = "123ccdd"; 

String[] s = { s1, s2, s3, s4 }; 
String regex = "(\\w)\\1(?!\\1)(\\w)\\2"; 

for(String a : s) { 
    Pattern pattern = Pattern.compile(regex); 
    Matcher matcher = pattern.matcher(a); 

    if (matcher.find()) 
     System.out.println(a + " ==> Success"); 
    else 
     System.out.println(a + " ==> Failure"); 
} 

輸出

aaaa123 ==>未能
aabb123 ==>成功
AA - 123 ==>未能
123ccdd ==>成功