Регулярни Изрази - Текстова Магия
- Теория
- Код
Регулярни Изрази в Java
Регулярните изрази (regular expressions) са мощен инструмент за работа с текст в програмирането. Те ви позволяват да търсите, замествате и манипулирате текст по сложни и гъвкави начини.
Основни Концепции:
Символи и Метасимволи:
- Обикновени символи: Представляват себе си (например, 'a', '1').
- Метасимволи: Имат специално значение (например,
.съответства на всякакъв символ,*означава повторение).
Примери за Метасимволи:
"b."ще съвпадне с 'b' последван от всякакъв символ (например "ba", "b2")."a*"съвпада с нула или повече 'a' (например "", "a", "aaa").
Използване на Регулярни Изрази в Java:
Java предоставя класовете Pattern и Matcher за работа с регулярни изрази.
Създаване на Pattern:
Pattern шаблон = Pattern.compile("b.");
Търсене на съвпадения с Matcher:
Matcher съвпадение = pattern.matcher("bat");
while (съвпадение.find()) {
System.out.println("Намерено съвпадение: " + съвпадение.group());
}
Квантификатори в Регулярни Изрази:
Квантификаторите са ключови в регулярните изрази. Те определят колко пъти даден елемент трябва да се повтори.
*(Звездичка): Съответства на нула или повече повторения на предходния елемент.+(Плюс): Съответства на едно или повече повторения на предходния елемент.?(Въпросителна): Съответства на нула или едно повторение на предходния елемент.{n}: Съответства точно наnброя повторения.{n,}: Съответства на най-малкоnброя повторения.{n,m}: Съответства на междуnиmброя повторения.
Примери:
"a*"съвпада с низове като "", "a", "aa", "aaa"..."a+"съвпада с "a", "aa", "aaa", но не и с ""."a?"съвпада с "", "a".
Групи и Групови Операции:
В регулярните изрази, групите позволяват комбинирането на части от израза в единици, които могат да се захващат, заместват или използват за референции.
- Обикновени групи (
()): Когато части от израза се поставят в скоби, те формират група. Например,(ab)+съвпада с едно или повече повторения на "ab". - Именувани групи (
(?<name>...)): Позволяват именуването на групи за по-лесно рефериране. Например,(?<year>\d{4})дефинира група за година.
Пример с групи:
Pattern шаблон = Pattern.compile("(ab)+");
Matcher съвпадение = шаблон.matcher("ababab");
while (съвпадение.find()) {
System.out.println("Намерено съвпадение: " + съвпадение.group());
}
Операции за Захващане и Заместване:
matcher.group(): Връща частта от низа, която съвпада с целия шаблон или специфична група.Pattern.matches(): Проверява дали целият низ съвпада с шаблона.matcher.replaceFirst()иmatcher.replaceAll(): Извършват заместване на съвпаденията в низа.
Пример за заместване:
String резултат = "abc123".replaceAll("\\d", "*");
System.out.println(резултат); // Извежда "abc***"
Специфични Символни Класове:
\\d: Съвпада с всяка цифра.\\w: Съвпада с всяка буква, цифра или подчертавка.\\s: Съвпада с всякакви пробелни символи.
Допълнителни Концепции в Регулярни Изрази:
Позитивни и Негативни Предпоставки (Lookaheads and Lookbehinds):
- Позитивна Предпоставка (Lookahead):
(?=pattern)- съвпада, ако следващата част от текста отговаря на 'pattern'. - Негативна Предпоставка (Negative Lookahead):
(?!pattern)- съвпада, ако следващата част от текста не отговаря на 'pattern'.
Нежадни Квантификатори (Non-Greedy Quantifiers):
*?,+?,??: Тези нежадни квантификатори търсят най-малкото възможно съвпадение, вместо най-голямото (както правят техните жадни версии).
Пример за нежадни квантификатори:
Pattern шаблон = Pattern.compile("<.*?>");
Matcher съвпадение = шаблон.matcher("<a><b><c>");
while (съвпадение.find()) {
System.out.println("Намерено съвпадение: " + съвпадение.group());
}
// Изведе всяка етикета поотделно, например <a>, <b>, <c>
Гранични Съвпадения (Boundary Matchers):
^и$: Съответстват с началото и края на реда.\\b: Съответства на граница на дума.\\B: Съответства на не-граница на дума.
Флагове на Регулярни Изрази
Флаговете модифицират поведението на регулярните изрази. Някои от основните флагове включват:
Pattern.CASE_INSENSITIVE: Игнорира разликите между малки и големи букви.Pattern.MULTILINE: Променя поведението на ^ и $, така че да съвпадат с началото и края на всеки ред, а не само с началото и края на целия текст.Pattern.DOTALL: Позволява на . (точка) да съвпада със символи за нов ред.
Пример с флагове:
Pattern шаблон = Pattern.compile("java", Pattern.CASE_INSENSITIVE);
Matcher съвпадение = шаблон.matcher("Java is fun");
System.out.println(съвпадение.find()); // Връща true
Допълнителни Методи и Техники:
matcher.lookingAt(): Проверява дали частта на началото на низа съвпада с шаблона.Escape символи: Важно е да се знае как да се "избяга" (escape) специални символи, когато искаме те да бъдат разглеждани като обикновени символи, например чрез използването на \.
Пример за използване на escape символи:
Pattern шаблон = Pattern.compile("\\$\\d+"); // Търси съвпадения като "$100"
Matcher съвпадение = шаблон.matcher("Цената е $100");
System.out.println(съвпадение.find()); // Връща true
За да направим лекцията още по-пълна и да обхванем всички аспекти на регулярните изрази в Java, можем да добавим следните теми:
Backreferences в Регулярни Изрази:
- Backreferences: Те се използват за съвпадение с част от низа, която вече е била захваната по-рано. Backreferences се създават чрез запазване на текст в групи със скоби и се реферират чрез
\n, къдетоnе номерът на групата.
Пример за backreferences:
Pattern шаблон = Pattern.compile("(\\b\\w+) \\1");
Matcher съвпадение = шаблон.matcher("hello hello");
System.out.println(съвпадение.find()); // Връща true, защото "hello" се повтаря
Шаблони за Характерни Класове:
- Характерни класове (
[...]): Те позволяват дефинирането на собствени множества от символи, които да съвпадат. Например,[abc]съвпада с всяко 'a', 'b', или 'c'.
Пример за характерни класове:
Pattern шаблон = Pattern.compile("[a-c]");
Matcher съвпадение = шаблон.matcher("bravo");
while (съвпадение.find()) {
System.out.println("Намерено съвпадение: " + съвпадение.group());
}
// Изведе "b" и "a"