Методи роботи з захоплюваними групами
Вихідний код програмиRegexDemo
включає виклик методу m.group()
. Метод group()
– одне із кількох методів класу Matcher
, орієнтованих працювати із захоплюваними групами:
-
Метод
int groupCount()
повертає кількість груп, що захоплюються в шаблоні співставника. Ця кількість не враховує спеціальну групу, що захоплюється, номер 0, відповідну шаблону в цілому. -
Метод
String group()
повертає символи попереднього знайденого збігу. Щоб повідомити про успішний пошук по порожньому рядку, цей метод повертає порожній рядок. Якщо порівняч ще не виконував пошуку або попередня операція пошуку завершилася невдачею, генерується винятокIllegalStateException
. -
Метод
String group(int group)
нагадує попередній метод, за винятком того, що повертає символи попереднього знайденого збігу, захоплені групою, номер якої задається параметромgroup
. Зверніть увагу, щоgroup(0)
еквівалентноgroup()
. Якщо в шаблоні немає групи з заданим номером, метод генерує винятокIndexOutOfBoundsException
. Якщо порівняч ще не виконував пошуку або попередня операція пошуку завершилася невдачею, генерується винятокIllegalStateException
. -
Метод
String group(String name)
повертає символи попереднього знайденого збігу, захоплені групою name. Якщо групи name у шаблоні немає, генерується винятокIllegalArgumentException
. Якщо порівняч ще не виконував пошуку або попередня операція пошуку завершилася невдачею, генерується винятокIllegalStateException
.
groupCount()
та group(int group)
:
Pattern p = Pattern.compile("(.(.(.)))");
Matcher m = p.matcher("abc");
m.find();
System.out.println(m.groupCount());
for (int i = 0; i <= m.groupCount(); i++)
System.out.println(i + ": " + m.group(i));
Результати виконання:
3
0: abc
1: abc
2: bc
3: c
Методи визначення позицій збігів
КласMatcher
надає кілька методів, що повертають початкову та кінцеву позиції збігу:
-
Метод
int start()
повертає початкову позицію попереднього знайденого збігу. Якщо порівняч ще не виконував пошуку або попередня операція пошуку завершилася невдачею, генерується винятокIllegalStateException
. -
Метод
int start(int group)
нагадує попередній метод, але повертає початкову позицію попереднього знайденого збігу групи, номер якої задається параметромgroup
. Якщо в шаблоні немає групи з заданим номером, метод генерує винятокIndexOutOfBoundsException
. Якщо порівняч ще не виконував пошуку або попередня операція пошуку завершилася невдачею, генерується винятокIllegalStateException
. -
Метод
int start(String name)
нагадує попередній метод, але повертає початкову позицію попереднього знайденого збігу групи з назвоюname
. Якщо групи, що захоплюється,name
у шаблоні немає, генерується винятокIllegalArgumentException
. Якщо порівняч ще не виконував пошуку або попередня операція пошуку завершилася невдачею, генерується винятокIllegalStateException
. -
Метод
int end()
повертає позицію останнього із символів попереднього знайденого збігу плюс 1. Якщо співставник ще не виконував пошуку або попередня операція пошуку завершилася невдачею, генерується винятокIllegalStateException
. -
Метод
int end(int group)
нагадує попередній метод, але повертає кінцеву позицію попереднього знайденого збігу групи, номер якої задається параметромgroup
. Якщо в шаблоні немає групи з заданим номером, метод генерує винятокIndexOutOfBoundsException
. Якщо порівняч ще не виконував пошуку або попередня операція пошуку завершилася невдачею, генерується винятокIllegalStateException
. -
Метод
int end(String name)
нагадує попередній метод, але повертає кінцеву позицію попереднього знайденого збігу групи з назвоюname
. Якщо групи, що захоплюється,name
у шаблоні немає, генерується винятокIllegalArgumentException
. Якщо порівняч ще не виконував пошуку або попередня операція пошуку завершилася невдачею, генерується винятокIllegalStateException
.
Pattern p = Pattern.compile("(.(.(.)))");
Matcher m = p.matcher("abcabcabc");
while (m.find())
{
System.out.println("Найдено " + m.group(2));
System.out.println(" начинается с позиции " + m.start(2) +
" и заканчивается на позиции " + (m.end(2) - 1));
System.out.println();
}
В результаті виконання цього прикладу виводиться таке:
Найдено bc
начинается с позиции 1 и заканчивается на позиции 2
Найдено bc
начинается с позиции 4 и заканчивается на позиции 5
Найдено bc
начинается с позиции 7 и заканчивается на позиции 8
Методи класу PatternSyntaxException
Примірник класуPatternSyntaxException
описує синтаксичну помилку у регулярному вираженні. Генерує такий виняток з методів compile()
і matches()
класу Pattern
, а формується за допомогою наступного конструктора: PatternSyntaxException(String desc, String regex, int index)
Цей конструктор зберігає вказаний опис ( desc
), регулярний вираз ( regex
) та позицію, на якій відбулася синтаксична помилка. Якщо місце синтаксичної помилки невідоме, значення index
встановлюється рівним -1
. Швидше за все, вам ніколи не знадобиться створювати екземпляри класу PatternSyntaxException
. Тим не менш, потрібно буде виймати вищезазначені значення при створенні форматованого повідомлення про помилку. Для цього можна скористатися такими методами:
- Метод
String getDescription()
повертає опис синтаксичної помилки. - Метод
int getIndex()
повертає або позицію, де сталася помилка, або -1, якщо позиція невідома. - Метод
String getPattern()
повертає помилкове регулярне вираження.
String getMessage()
повертає багаторядковий рядок зі значеннями, повернутими з попередніх методів разом із візуальною вказівкою на місце синтаксичної помилки у шаблоні. Що таке синтаксична помилка? Ось приклад: java RegexDemo (?itree Treehouse
У цьому випадку ми забули вказати закриває метасимвол дужки ( )
) у вкладеному прапорі. Ось що виводиться внаслідок цієї помилки:
regex = (?itree
input = Treehouse
Неправильное регулярное выражение: Unknown inline modifier near index 3
(?itree
^
Описание: Unknown inline modifier
Позиция: 3
Неправильный шаблон: (?itree
Створення корисних програм з регулярними виразами за допомогою API Regex
Регулярні вирази дозволяють створювати додатки для обробки тексту, які мають великі можливості. У цьому розділі ми покажемо вам дві зручні програми, які, сподіваємося, спонукають вас далі дослідити класи та методи API Regex. У другому додатку ви познайомитеся з Lexan: бібліотекою багаторазового коду для виконання лексичного аналізу.Регулярні вирази та документація
Документування – одне з обов'язкових завдань розробки професійно виконаного програмного забезпечення. На щастя, регулярні висловлювання можуть допомогти вам з багатьма аспектами створення документації. Код у лістингу 1 витягує рядки, що містять однорядкові та багаторядкові коментарі в стилі мови C з вихідного файлу і записує їх в інший файл. Щоб код працював, коментарі мають бути розташовані в одному рядку. Лістинг 1. Вилучення коментарівimport java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;
public class ExtCmnt
{
public static void main(String[] args)
{
if (args.length != 2)
{
System.err.println("Способ применения: java ExtCmnt infile outfile");
return;
}
Pattern p;
try
{
// Следующий шаблон определяет многострочные комментарии,
// располагающиеся в одной строке (например, /* одна строка */)
// и однострочные комментарии (например, // якая-то строка).
// Комментарий может располагаться в любом месте строки.
p = Pattern.compile(".*/\\*.*\\*/|.*//.*$");
}
catch (PatternSyntaxException pse)
{
System.err.printf("Синтаксическая ошибка в регулярном выражении: %s%n", pse.getMessage());
System.err.printf("Описание ошибки: %s%n", pse.getDescription());
System.err.printf("Позиция ошибки: %s%n", pse.getIndex());
System.err.printf("Ошибочный шаблон: %s%n", pse.getPattern());
return;
}
try (FileReader fr = new FileReader(args[0]);
BufferedReader br = new BufferedReader(fr);
FileWriter fw = new FileWriter(args[1]);
BufferedWriter bw = new BufferedWriter(fw))
{
Matcher m = p.matcher("");
String line;
while ((line = br.readLine()) != null)
{
m.reset(line);
if (m.matches()) /* Должна соответствовать вся строка */
{
bw.write(line);
bw.newLine();
}
}
}
catch (IOException ioe)
{
System.err.println(ioe.getMessage());
return;
}
}
}
Метод main()
з лістингу 1 спочатку перевіряє правильність синтаксису командного рядка, після чого компілює призначене для виявлення одно-і багаторядкових коментарів регулярне вираження об'єкт класу Pattern
. Якщо немає винятку PatternSyntaxException
, спосіб main()
відкриває вихідний файл, створює цільовий файл, отримує співставник для зіставлення кожного прочитаного рядка з шаблоном, після чого читає вихідний файл рядково. Для кожного рядка виконується зіставлення її із шаблоном коментаря. У разі успіху метод main()
записує рядок (з наступним символом нового рядка) у цільовий файл (ми розглянемо логіку файлового вводу/виводу у майбутньому навчальному посібнику Java 101). Скомпілюйте листинг 1 таким чином: javac ExtCmnt.java
Виконайте програму з файломExtCmnt.java
як вхідний: java ExtCmnt ExtCmnt.java out
Ви повинні отримати у файлі out наступні результати:
// Следующий шаблон определяет многострочные комментарии,
// располагающиеся в одной строке (например, /* одна строка */)
// и однострочные комментарии (например, // якая-то строка).
// Комментарий может располагаться в любом месте строки.
p = Pattern.compile(".*/\\*.*\\*/|.*//.*$");
if (m.matches()) /* Должна соответствовать вся строка */
У рядку шаблону .*/\\*.*\\*/|.*//.*$
метасимвол вертикальної риси |
грає роль логічного оператора АБО, що вказує на необхідність співставника використовувати лівий операнд з конструкції даного регулярного виразу для пошуку відповідності в тексті співставника. Якщо відповідностей немає, співставник використовує правий операнд з конструкції даного регулярного вираження для ще однієї спроби пошуку (метасимволи дужок у групі, що захоплюється, теж формують логічний оператор). Регулярні вирази в Java, частина 5
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ