Экранировка спецсимволов в регулярках Java
Предположим, что нужно сделать так, чтобы спецсимвол обозначал сам себя. Для этого его следует экранировать. Посмотрим на примерах.
В следующем примере автор регулярки хотел,
чтобы шаблон поиска выглядел так: буква
'a', затем плюс '+', затем
буква 'x'. Однако, автор кода
не заэкранировал символ '+' и поэтому
шаблон поиска самом деле он выглядит так:
буква 'a' один или более раз,
потом буква 'x':
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Main {
public static void main(String[] args) {
String txt = "a+x ax aax aaax";
Pattern pattern = Pattern.compile("a+x");
Matcher matcher = pattern.matcher(txt);
String res = matcher.replaceAll("!");
System.out.println(res);
}
}
Результат выполнения кода:
"a+x ! ! !"
А сейчас автор заэкранировал плюс обратным
слешем. Теперь шаблон поиска выглядит так,
как надо: буква 'a', затем плюс
'+', затем буква 'x':
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Main {
public static void main(String[] args) {
String txt = "a+x ax aax aaax";
Pattern pattern = Pattern.compile("a\\+x");
Matcher matcher = pattern.matcher(txt);
String res = matcher.replaceAll("!");
System.out.println(res);
}
}
Результат выполнения кода:
"! ax aax aaax"
В данном примере шаблон выглядит так:
буква 'a', затем точка '.',
затем буква 'x':
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Main {
public static void main(String[] args) {
String txt = "a.x abx azx";
Pattern pattern = Pattern.compile("a\\.x");
Matcher matcher = pattern.matcher(txt);
String res = matcher.replaceAll("!");
System.out.println(res);
}
}
Результат выполнения кода:
"! abx azx"
А следующем примере автор забыл заэкранировать слеш и под регулярку попали все подстроки, так как незаэкранированная точка обозначает любой символ:
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Main {
public static void main(String[] args) {
String txt = "a.x abx azx";
Pattern pattern = Pattern.compile("a.x");
Matcher matcher = pattern.matcher(txt);
String res = matcher.replaceAll("!");
System.out.println(res);
}
}
Результат выполнения кода:
"! ! !"
Обратите внимание на то, что если вы забудете обратный слеш для точки (когда она должна обозначать сама себя) - этого можно даже не заметить:
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Main {
public static void main(String[] args) {
Pattern pattern = Pattern.compile("a.x");
Matcher matcher = pattern.matcher("a.x");
String res = matcher.replaceAll("!");
System.out.println(res);
}
}
Визуально работает правильно (так как точка
обозначает любой символ, в том числе и
обычную точку '.'). Но если поменять
строку, в которой происходят замены - мы
увидим нашу ошибку:
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Main {
public static void main(String[] args) {
Pattern pattern = Pattern.compile("a.x");
Matcher matcher = pattern.matcher("a.x abx azx");
String res = matcher.replaceAll("!");
System.out.println(res);
}
}
Если экранировать обычный символ - ничего страшного не случится - он все равно будет обозначать сам себя. Исключение - цифры, их нельзя экранировать.
Часто возникает сомнение, является ли данный символ специальным. Некоторые доходят до того, что экранируют все подозрительные символы подряд. Однако, это плохая практика (захламляет регулярку обратными слешами).
Являются спецсимволами: $ ^. * + ? \ / {} [] () |
Не являются спецсимволами: @ :, ' " - _ = < > % # ~ `& !
Дана строка:
public class Main {
public static void main(String[] args) {
String txt = "a.a aba aea";
}
}
Напишите регулярку, которая найдет строку
'a.a', не захватив остальные.
Дана строка:
public class Main {
public static void main(String[] args) {
String txt = "2+3 223 2223";
}
}
Напишите регулярку, которая найдет строку
'2+3', не захватив остальные.
Дана строка:
public class Main {
public static void main(String[] args) {
String txt = "23 2+3 2++3 2+++3 345 567";
}
}
Напишите регулярку, которая найдет строки
'2+3', '2++3', '2+++3',
не захватив остальные (+ может быть любое
количество).
Дана строка:
public class Main {
public static void main(String[] args) {
String txt = "23 2+3 2++3 2+++3 445 677";
}
}
Напишите регулярку, которая найдет строки
'23', '2+3', '2++3',
'2+++3', не захватив остальные.
Дана строка:
public class Main {
public static void main(String[] args) {
String txt = "*+ *q+ *qq+ *qqq+ *qqq qqq+";
}
}
Напишите регулярку, которая найдет строки
'*q+', '*qq+', '*qqq+',
не захватив остальные.
Дана строка:
public class Main {
public static void main(String[] args) {
String txt = "[abc] {abc} abc (abc) [abc]";
}
}
Напишите регулярку, которая найдет строки
в квадратных скобках и заменит их на
'!'.