Обратные ссылки (backreferences) в регулярных выражениях Java – очень полезная возможность, поддерживаемая Java машиной.
Для того чтобы понять, что такое обратные ссылки, сначала надо научиться понимать, что такое группа (group). Группа в регулярных выражениях рассматривает множество символов как единое целое. Группы создаются помещением символов в круглые скобки – ”()”. Одна пара круглых скобок – одна группа.
Обратные ссылки удобны тем, что мы можем повторять паттерны поиска без их непосредственного копирования. Нам достаточно просто сослаться на ранее определенную группу при помощи конструкции вида \N, где N - это номер группы. Следующие 2 примера позволяют почувствовать удобство обратных ссылок.
Пример 1: поиск повторяющегося паттерна
Конструкция вида (\d\d\d)\1 соответствует строке 123123, но не строке 123456.String str = "ля123123ля";
Pattern p = Pattern.compile("(\\d\\d\\d)\\1");
Matcher m = p.matcher(str);
System.out.println(m.groupCount());
while (m.find()) {
String word = m.group();
System.out.println(word + " " + m.start() + " " + m.end());
}
Вывод:
1
123123 2 8
Примечание переводчика!
Здесь я как переводчик хочу проявить небольшую вольность и вставить комментарии от себя, т.к. сам только разбираюсь с регулярными выражениями и надеюсь, что меня с матюгами:) поправят, если то, что я напишу ниже, будет ошибкой:
1) Метод groupCount()
Выдает количество групп, заданных в паттерне, поэтому даже если входная строка будет "ля123456ля", не укладывающая в шаблон, на экран все равно будет выведена цифра 1.
2) Метод find()
Ищет очередную группу, но возвращает лишь булевого значение: true – нашел, false – не нашел
3) Метод group()
Возвращает последнюю найденную по паттерну подстроку. В данном случае 123123
4) Метод start()
Возвращает позицию найденной подстроки в исходной строке (нумерация, разумеется, с нуля)
5) Метод end()
Возвращает позицию в исходной строке, следующую сразу за найденной подстрокой. Таким образом, это значение указывает не на последний символ из найденной подстроки в исходной строке, а на следующий за ним.
Пример 2: Поиск повторяющихся слов
String pattern = "\\b(\\w+)\\b[\\w\\W]*\\b\\1\\b";
Pattern p = Pattern.compile(pattern, Pattern.CASE_INSENSITIVE);
String phrase = "unique is not duplicate but unique, Duplicate is duplicate.";
Matcher m = p.matcher(phrase);
while (m.find()) {
String val = m.group();
System.out.println("Найденная последовательность символов: \"" + val + "\"");
System.out.println("Слово-дубликат: " + m.group(1) + "\n");
}
Вывод:
Найденная последовательность символов: "unique is not duplicate but unique"
Слово-дубликат: unique
Найденная последовательность символов: "Duplicate is duplicate"
Слово-дубликат: Duplicate
Обратите внимание, что такой способ находить повторяющиеся слова (при помощи регулярных выражений) не является оптимальным. Например, в примере выше, первое слово “duplicate” пропускается.
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ