模式:如何在字符类中减去匹配的字符?

时间:2012-02-07 09:44:54

标签: java regex

是否可以减去角色类中匹配的角色?

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 个答案:

答案 0 :(得分:3)

使用

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

您的角色将分组13

这可以通过使用否定前瞻来确保第一个字符组中第二个字符后面的字符是不同的字符。

答案 1 :(得分:1)

您使用错误的工具进行工作。通过一切使用正则表达式来检测字符对对,但您可以使用!=来测试对中的字符是否相同。说真的,没有理由在正则表达式中执行所有 - 它会产生不可读的,不可移植的代码,并且除了“看起来很酷”之外没有任何其他好处。

答案 2 :(得分: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 ==>成功