Шаблон: как вычесть совпадающий символ в классе символов? - PullRequest
5 голосов
/ 07 февраля 2012

Можно ли вычесть соответствующий символ в классе символов?

Документы Java содержат примеры классов символов с вычитанием:

[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 ]

3 голосов
/ 07 февраля 2012

Используйте

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

Ваши персонажи будут в группах 1 и 3.

Это работает с использованием отрицательного взгляда, чтобы убедиться, что символ, следующий за вторым символом в первой группе символов, является другим символом.

1 голос
/ 07 февраля 2012

Попробуйте

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

(?!\\1) является негативным прогнозом , это гарантирует, что содержимое \\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 ==>Успех

1 голос
/ 07 февраля 2012

Вы используете не тот инструмент для работы.Обязательно используйте регулярное выражение для обнаружения пар пар символов, но вы можете просто использовать !=, чтобы проверить, совпадают ли символы в парах.Серьезно, нет никаких оснований делать все в регулярном выражении - это делает нечитабельный непереносимый код и не дает вам никакой выгоды, кроме как «выглядеть круто».

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...