Регулярные выражения java примеры
Java предоставляет пакет java.util.regex для сопоставления с шаблоном с регулярными выражениями. Регулярные выражения Java очень похожи на язык программирования Perl и очень просты в освоении.
Регулярное выражение(regular expressions) – это специальная последовательность символов, которая помогает вам сопоставлять или находить другие строки или наборы строк, используя специальный синтаксис, содержащийся в шаблоне. Их можно использовать для поиска, редактирования или манипулирования текстом и данными.
Шаблон поиска может быть любым из простого символа, фиксированной строки или сложного выражения, содержащего специальные символы, описывающие шаблон. Шаблон, определенный выражением, может совпадать один или несколько раз или не совпадать для данной строки.
Шаблон применяется к тексту слева направо. Как только исходный символ был найден, его нельзя уже использовать повторно. Например, выражение aba будет соответствовать ababababa только два раза (aba_aba__)
Пакет java.util.regex в основном состоит из следующих трех классов:
- Класс Pattern – Объект Pattern представляет собой скомпилированное представление регулярного выражения. Класс Pattern не предоставляет общедоступных конструкторов. Чтобы создать шаблон, вы должны сначала вызвать один из его открытых статических методов compile(), который затем вернет объект Pattern. Эти методы принимают выражение в качестве первого аргумента.
- Класс Matcher – объект Matcher – это механизм, который интерпретирует шаблон и выполняет операции сопоставления с входной строкой. Как и класс Pattern, Matcher не определяет общедоступных конструкторов. Вы получаете объект Matcher, вызывая метод matcher() для объекта Pattern.
- PatternSyntaxException – Объект PatternSyntaxException является непроверенным исключением, которое указывает на синтаксическую ошибку в образце выражения.
Простым примером является строка. Например, Hello World соответствует строке «Hello World». , (точка) является еще одним примером. Точка соответствует любому отдельному символу; будет соответствовать, например, «а» или «1».
выражение | соответствие |
---|---|
это текст | соответствует “это текст” |
this\s+is\s+text | Соответствует слову «this», за которым следуют один или несколько пробелов, за которыми следует слово «is», за которыми следуют один или несколько пробелов, за которыми следует слово «text». |
^\d+(\.\d+)? | ^ определяет, что выражение должно начинаться с начала новой строки. \ d + соответствует одной или нескольким цифрам. ? делает утверждение в скобках необязательным. \. соответствует “.”, скобки используются для группировки. Соответствует, например, “5”, “1,5” и “2.21”. |
Capturing groups
Группы захвата(Capturing groups) – это способ рассматривать несколько символов как единое целое. Они создаются путем помещения символов, которые будут сгруппированы, в набор скобок.
Например, (dog) создает одну группу, содержащую буквы «d», «o» и «g».
Группы захвата нумеруются путем подсчета открывающих скобок слева направо. В выражении ((A) (B (C))), например, есть четыре такие группы –
Чтобы узнать, сколько групп присутствует в выражении, вызовите метод groupCount для объекта соответствия. Метод groupCount возвращает int, показывающий количество групп захвата, присутствующих в шаблоне сопоставителя.
Существует также специальная группа, группа 0, которая всегда представляет все выражение. Эта группа не включена в общее количество, сообщенное groupCount.
В следующем примере показано, как найти строку цифр из заданной буквенно-цифровой строки:
import java.util.regex.Matcher; import java.util.regex.Pattern; public class RegexMatches < public static void main( String args[] ) < // Строка для сканирования, чтобы найти шаблон. String line = "This order was placed for QT3000! OK?"; String pattern = "(.*)(\\d+)(.*)"; // Создаем объект Pattern Pattern r = Pattern.compile(pattern); // Теперь создаем объект соответствия. Matcher m = r.matcher(line); if (m.find( )) < System.out.println("Found value: " + m.group(0) ); System.out.println("Found value: " + m.group(1) ); System.out.println("Found value: " + m.group(2) ); >else < System.out.println("NO MATCH"); >> >
Это даст следующий результат:
Found value: This order was placed for QT3000! OK?
Found value: This order was placed for QT300
Found value: 0
Синтаксис регулярных выражений в Java
Вот таблица со списком всех синтаксисов регулярных выражений, доступных в Java:
Subexpression | Соответствия |
---|---|
^ | Соответствует началу строки. |
$ | Соответствует концу строки. |
. | любому отдельному символу, кроме новой строки. Использование опции m позволяет ему соответствовать и новой строке. |
[…] | любому отдельному символу в скобках. |
[^…] | любому отдельному символу не в скобках. |
\A | Начало всей строки. |
\z | Конец всей строки. |
\Z | Конец всей строки, кроме допустимого конечного terminator. |
re* | Соответствует 0 или более вхождений предыдущего выражения. |
re+ | Соответствует 1 или более из предыдущего. |
re? | Соответствует 0 или 1 вхождению предыдущего выражения. |
re | Совпадает ровно с числом вхождений предыдущего выражения. |
re | Соответствует n или более вхождений предыдущего выражения. |
re | Соответствует не менее n и не более m вхождений предыдущего выражения. |
a| b | Соответствует либо a, либо b. |
(re) | Группирует регулярные выражения и запоминает сопоставленный текст. |
(?: re) | Группирует без запоминания сопоставленного текста. |
(?> re) | Соответствует независимому паттерну без возврата. |
\w | Слову из символов. |
\W | несловесным символам. |
\s | Соответствует пробелу. Эквивалентно [\t\n\r\f]. |
\S | без пробелов. |
\d | Соответствует цифрам. Эквивалентно 6. |
\D | Совпадает с “не цифрами”. |
\A | началу строки. |
\Z | концу строки. Если новая строка существует, она совпадает непосредственно перед новой строкой. |
\z | концу строки. |
\G | точке, где закончился последний. |
\n | Обратная ссылка для захвата номера группы “n”. |
\b | Соответствует границам слов вне скобок. Соответствует возврату (0x08) внутри скобок. |
\B | границам без слов. |
\n, \t, etc. | Сопоставляет переводы строк, возврат каретки, вкладки и т. д. |
\Q | Escape (цитата) все символы до \E. |
\E | Завершает цитирование, начинающееся с \ Q. |
Обратная косая черта имеет предопределенное значение в Java. Вы должны использовать двойную обратную косую черту \\, чтобы определить одну обратную косую черту. Если вы хотите определить \w, то вы должны использовать \\w.
Методы класса Matcher
Вот список полезных методов экземпляра – Index methods предоставляют полезные значения индекса, которые точно показывают, где совпадение было найдено во входной строке.
Методы Study
Методы Study проверяют входную строку и возвращают логическое значение, указывающее, найден ли шаблон.
№ | Метод и описание |
---|---|
1 | public boolean lookingAt() Пытается сопоставить входную последовательность, начиная с начала, с шаблоном. |
2 | public boolean find() Пытается найти следующую подпоследовательность входной последовательности, которая соответствует шаблону. |
3 | public boolean find(int start) Сбрасывает это сопоставление и затем пытается найти следующую подпоследовательность входной последовательности, которая соответствует шаблону, начиная с указанного индекса. |
4 | public boolean matches() Попытки сопоставить весь регион с паттерном. |
Методы замены
Методы замены являются полезными методами для замены текста во входной строке.
Методы начала и конца
Ниже приведен пример, который подсчитывает, сколько раз слово cat (кот) появляется во входной строке:
import java.util.regex.Matcher; import java.util.regex.Pattern; public class RegexMatches < private static final String REGEX = "\\bcat\\b"; private static final String INPUT = "cat cat cat cattie cat"; public static void main( String args[] ) < Pattern p = Pattern.compile(REGEX); Matcher m = p.matcher(INPUT); // get a matcher object int count = 0; while(m.find()) < count++; System.out.println("Match number "+count); System.out.println("start(): "+m.start()); System.out.println("end(): "+m.end()); >> >
Получим результат:
Match number 1
start(): 0
end(): 3
Match number 2
start(): 4
end(): 7
Match number 3
start(): 8
end(): 11
Match number 4
start(): 19
end(): 22
Этот пример использует границы слов, чтобы гарантировать, что буквы “c” “a” “t” не являются просто подстрокой в более длинном слове. Это также дает некоторую полезную информацию о том, где во входной строке произошло совпадение.
Метод start возвращает начальный индекс подпоследовательности, захваченной данной группой во время предыдущей операции сопоставления, а end возвращает индекс последнего сопоставленного символа плюс один.
Методы поиска(lookingAt)
Методы match и LookingAt пытаются сопоставить входную последовательность с шаблоном. Разница, однако, заключается в том, что для matches требуется сопоставление всей входной последовательности, а для lookingAt – нет.
Оба метода всегда начинаются с начала строки ввода. Вот пример:
import java.util.regex.Matcher; import java.util.regex.Pattern; public class RegexMatches < private static final String REGEX = "foo"; private static final String INPUT = "fooooooooooooooooo"; private static Pattern pattern; private static Matcher matcher; public static void main( String args[] ) < pattern = Pattern.compile(REGEX); matcher = pattern.matcher(INPUT); System.out.println("Current REGEX is: "+REGEX); System.out.println("Current INPUT is: "+INPUT); System.out.println("lookingAt(): "+matcher.lookingAt()); System.out.println("matches(): "+matcher.matches()); >>
Получим следующий результат:
Current REGEX is: foo
Current INPUT is: fooooooooooooooooo
lookingAt(): true
matches(): false
Методы replaceFirst и replaceAll
Методы replaceFirst и replaceAll заменяют текст, соответствующий заданному регулярному выражению. replaceFirst заменяет первое вхождение, а replaceAll заменяет все вхождения.
Вот пример, объясняющий их работу:
import java.util.regex.Matcher; import java.util.regex.Pattern; public class RegexMatches < private static String REGEX = "dog"; private static String INPUT = "The dog says meow. " + "All dogs say meow."; private static String REPLACE = "cat"; public static void main(String[] args) < Pattern p = Pattern.compile(REGEX); // получаем объект соответствия Matcher m = p.matcher(INPUT); INPUT = m.replaceAll(REPLACE); System.out.println(INPUT); >>
И теперь вывод:
The cat says meow. All cats say meow.
Методы appendReplace и appendTail
Класс Matcher также предоставляет методы appendReplacement и appendTail для замены текста.
import java.util.regex.Matcher; import java.util.regex.Pattern; public class RegexMatches < private static String REGEX = "a*b"; private static String INPUT = "aabfooaabfooabfoob"; private static String REPLACE = "-"; public static void main(String[] args) < Pattern p = Pattern.compile(REGEX); Matcher m = p.matcher(INPUT); StringBuffer sb = new StringBuffer(); while(m.find()) < m.appendReplacement(sb, REPLACE); >m.appendTail(sb); System.out.println(sb.toString()); > >
Методы класса PatternSyntaxException
PatternSyntaxException – это непроверенное исключение, которое указывает на синтаксическую ошибку в шаблоне. Класс PatternSyntaxException предоставляет следующие методы, чтобы помочь вам определить, что пошло не так:
Примеры
Напишите регулярное выражение, которое соответствует любому номеру телефона.
Телефонный номер в этом примере состоит либо из 7 номеров подряд, либо из 3 номеров, пробела или тире, а затем из 4 номеров.
package regex.phonenumber; import org.junit.Test; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; public class CheckPhone < @Test public void testSimpleTrue() < String pattern = "\\d\\d\\d([,\\s])?\\d\\d\\d\\d"; String s= "1233323322"; assertFalse(s.matches(pattern)); s = "1233323"; assertTrue(s.matches(pattern)); s = "123 3323"; assertTrue(s.matches(pattern)); >>
В следующем примере проверяется, содержит ли текст число из 3 цифр.
package regex.numbermatch; import java.util.regex.Matcher; import java.util.regex.Pattern; import org.junit.Test; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; public class CheckNumber < @Test public void testSimpleTrue() < String s= "1233"; assertTrue(test(s)); s= "0"; assertFalse(test(s)); s = "29 Kasdkf 2300 Kdsdf"; assertTrue(test(s)); s = "99900234"; assertTrue(test(s)); >public static boolean test (String s)< Pattern pattern = Pattern.compile("\\d"); Matcher matcher = pattern.matcher(s); if (matcher.find()) < return true; >return false; > >
В следующем примере показано как извлечь все действительные ссылки с веб-страницы. Не учитывает ссылки, начинающиеся с «javascript:» или «mailto:».
package regex.weblinks; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.net.MalformedURLException; import java.net.URL; import java.util.ArrayList; import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; public class LinkGetter < private Pattern htmltag; private Pattern link; public LinkGetter() < htmltag = Pattern.compile("]*href=\"[^>]*>(.*?)"); link = Pattern.compile("href=\"[^>]*\">"); > public List getLinks(String url) < List links = new ArrayList(); try < BufferedReader bufferedReader = new BufferedReader( new InputStreamReader(new URL(url).openStream())); String s; StringBuilder builder = new StringBuilder(); while ((s = bufferedReader.readLine()) != null) < builder.append(s); >Matcher tagmatch = htmltag.matcher(builder.toString()); while (tagmatch.find()) < Matcher matcher = link.matcher(tagmatch.group()); matcher.find(); String link = matcher.group().replaceFirst("href=\"", "") .replaceFirst("\">", "") .replaceFirst("\"[\\s]?target=\"[a-zA-Z_0-9]*", ""); if (valid(link)) < links.add(makeAbsolute(url, link)); >> > catch (MalformedURLException e) < e.printStackTrace(); >catch (IOException e) < e.printStackTrace(); >return links; > private boolean valid(String s) < if (s.matches("javascript:.*|mailto:.*")) < return false; >return true; > private String makeAbsolute(String url, String link) < if (link.matches("http://.*")) < return link; >if (link.matches("/.*") && url.matches(".*$[^/]")) < return url + "/" + link; >if (link.matches("[^/].*") && url.matches(".*[^/]")) < return url + "/" + link; >if (link.matches("/.*") && url.matches(".*[/]")) < return url + link; >if (link.matches("/.*") && url.matches(".*[^/]")) < return url + link; >throw new RuntimeException("Cannot make the link absolute. Url: " + url + " Link " + link); > >
Поиск дублированных слов.
\b(\w+)\s+\1\b
\b является границей слова и \1 ссылается на совпадение первой группы, то есть первого слова. (?!-in)\b(\w+) \1\b находит повторяющиеся слова, если они не начинаются с “-in”. Добавьте (?S) для поиска по нескольким строкам.
Поиск элементов, которые начинаются с новой строки.
(\n\s*)title
Также можете посмотреть официальную документацию тут.
Средняя оценка 3.8 / 5. Количество голосов: 20