Поиск…


Вступление

Регулярное выражение представляет собой специальную последовательность символов, которая помогает в сопоставлении или поиске других строк или наборов строк с использованием специализированного синтаксиса, содержащегося в шаблоне. Java поддерживает регулярное использование выражений через пакет java.util.regex . Эта тема должна представить и помочь разработчикам понять больше с примерами того, как регулярные выражения должны использоваться в Java.

Синтаксис

  • Pattern patternName = Pattern.compile (regex);
  • Matcher matcherName = patternName.matcher (textToSearch);
  • matcherName.matches () // Возвращает true, если textToSearch точно соответствует регулярному выражению
  • matcherName.find () // Ищет через textToSearch для первого экземпляра подстроки, соответствующей регулярному выражению. Последующие вызовы будут искать оставшуюся часть строки.
  • matcherName.group (groupNum) // Возвращает подстроку внутри группы захвата
  • matcherName.group (groupName) // Возвращает подстроку внутри указанной группы захвата (Java 7+)

замечания

импорт

Вам нужно будет добавить следующий импорт, прежде чем вы сможете использовать Regex:

import java.util.regex.Matcher
import java.util.regex.Pattern

Ловушки

В java обратная косая черта сбрасывается с двойной обратной косой чертой, поэтому обратная косая черта в строке регулярного выражения должна вводиться как двойной обратный слэш. Если вам нужно избежать двойной обратной косой черты (чтобы соответствовать одной обратной косой чертой с регулярным выражением, вам нужно ввести ее в виде четырехкратной обратной косой черты.

Обозначенные важные символы

символ Описание
* Совпадение предыдущего символа или подвыражения 0 или более раз
+ Совпадение предыдущего символа или подвыражения 1 или более раз
? Соответствует предыдущему символу или подвыражению 0 или 1 раз

дальнейшее чтение

Тема регулярного выражения содержит больше информации о регулярных выражениях.

Использование групп захвата

Если вам нужно извлечь часть строки из входной строки, мы можем использовать группы захвата regex.

В этом примере мы начнем с простого регулярного выражения номера телефона:

\d{3}-\d{3}-\d{4}

Если скобки добавлены в регулярное выражение, каждый набор круглых скобок считается группой захвата . В этом случае мы используем так называемые нумерованные группы захвата:

(\d{3})-(\d{3})-(\d{4})
^-----^ ^-----^ ^-----^
Group 1 Group 2 Group 3

Прежде чем мы сможем использовать его в Java, мы не должны забывать следовать правилам строк, избегая обратных косых черт, в результате получим следующий шаблон:

"(\\d{3})-(\\d{3})-(\\d{4})"

Сначала нам нужно скомпилировать шаблон регулярного выражения, чтобы создать Pattern а затем нам нужен Matcher для соответствия нашей входной строке с шаблоном:

Pattern phonePattern = Pattern.compile("(\\d{3})-(\\d{3})-(\\d{4})");
Matcher phoneMatcher = phonePattern.matcher("abcd800-555-1234wxyz");

Далее, Matcher должен найти первую подпоследовательность, которая соответствует регулярному выражению:

phoneMatcher.find();

Теперь, используя групповой метод, мы можем извлечь данные из строки:

String number = phoneMatcher.group(0); //"800-555-1234" (Group 0 is everything the regex matched)
String aCode = phoneMatcher.group(1); //"800"
String threeDigit = phoneMatcher.group(2); //"555"
String fourDigit = phoneMatcher.group(3); //"1234"

Примечание: Matcher.group() может использоваться вместо Matcher.group(0) .

Java SE 7

Java 7 представила названные группы захвата. Именованные группы захвата функционируют так же, как и нумерованные группы захвата (но с именем вместо числа), хотя есть небольшие изменения синтаксиса. Использование названных групп захвата улучшает читаемость.

Мы можем изменить приведенный выше код для использования названных групп:

(?<AreaCode>\d{3})-(\d{3})-(\d{4})
^----------------^ ^-----^ ^-----^
AreaCode           Group 2 Group 3

Чтобы получить содержимое «AreaCode», мы можем вместо этого использовать:

String aCode = phoneMatcher.group("AreaCode"); //"800"

Использование регулярных выражений с пользовательским поведением путем компиляции шаблона с флагами

Pattern можно скомпилировать с помощью флагов, если регулярное выражение используется как литерал String , используйте встроенные модификаторы:

Pattern pattern = Pattern.compile("foo.", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
pattern.matcher("FOO\n").matches(); // Is true.

/* Had the regex not been compiled case insensitively and singlelined,
 * it would fail because FOO does not match /foo/ and \n (newline)
 * does not match /./.
 */

Pattern anotherPattern = Pattern.compile("(?si)foo");
anotherPattern.matcher("FOO\n").matches(); // Is true.

"foOt".replaceAll("(?si)foo", "ca"); // Returns "cat".

Персонажи побега

В общем-то

Чтобы использовать регулярные выражения определенных символов ( ?+| т. Д.) В их буквальном значении, их нужно избегать. В обычном регулярном выражении это выполняется обратным слэшем \ . Однако, поскольку это имеет особое значение в Java-строках, вам нужно использовать двойную обратную косую черту \\ .

Эти два примера не будут работать:

"???".replaceAll ("?", "!"); //java.util.regex.PatternSyntaxException
"???".replaceAll ("\?", "!"); //Invalid escape sequence

Этот пример работает

"???".replaceAll ("\\?", "!"); //"!!!"

Разделение строки с разделителями труб

Это не возвращает ожидаемый результат:

"a|b".split ("|"); // [a, |, b]

Это возвращает ожидаемый результат:

"a|b".split ("\\|"); // [a, b]

Сбрасывание обратной косой черты \

Это даст ошибку:

"\\".matches("\\"); // PatternSyntaxException
"\\".matches("\\\"); // Syntax Error

Это работает:

"\\".matches("\\\\"); // true

Согласование с литералом регулярного выражения.

Если вам нужно сопоставить символы, которые являются частью синтаксиса регулярных выражений, вы можете пометить все или часть шаблона как литерал регулярного выражения.

\Q обозначает начало литерала регулярного выражения. \E обозначает конец литерала регулярного выражения.

// the following throws a PatternSyntaxException because of the un-closed bracket
"[123".matches("[123");

// wrapping the bracket in \Q and \E allows the pattern to match as you would expect.
"[123".matches("\\Q[\\E123"); // returns true

Более простой способ сделать это без необходимости запоминать escape-последовательности \Q и \E - использовать Pattern.quote()

"[123".matches(Pattern.quote("[") + "123"); // returns true

Не соответствует заданной строке

Чтобы сопоставить то, что не содержит заданную строку, можно использовать отрицательный просмотр:

Синтаксис Regex: (?!string-to-not-match)

Пример:

//not matching "popcorn"
String regexString = "^(?!popcorn).*$";
System.out.println("[popcorn] " + ("popcorn".matches(regexString) ? "matched!" : "nope!"));
System.out.println("[unicorn] " + ("unicorn".matches(regexString) ? "matched!" : "nope!"));

Выход:

[popcorn] nope!
[unicorn] matched!

Соответствие обратной косой черты

Если вы хотите совместить обратную косую черту в своем регулярном выражении, вам придется ее избежать.

Обратная косая черта - это символ escape в регулярных выражениях. Вы можете использовать '\\', чтобы ссылаться на одну обратную косую черту в регулярном выражении.

Однако обратная косая черта также является символом escape в строках строки Java. Для того, чтобы регулярное выражение из строки буквальным, вы должны бежать каждый из его обратной косой черты. В строковом литерале «\\\\» можно использовать для создания регулярного выражения с «\\», которое, в свою очередь, может соответствовать «\».

Например, рассмотрите соответствующие строки, такие как «C: \ dir \ myfile.txt». Регулярное выражение ([A-Za-z]):\\(.*) Будет совпадать и предоставить букву диска в качестве группы захвата. Обратите внимание на удвоенную обратную косую черту.

Чтобы выразить этот шаблон в строковом литерале Java, каждая обратная косая черта в регулярном выражении должна быть экранирована.

    String path = "C:\\dir\\myfile.txt";
    System.out.println( "Local path: " + path ); // "C:\dir\myfile.txt"
    
    String regex = "([A-Za-z]):\\\\.*"; // Four to match one
    System.out.println("Regex:      " + regex ); // "([A-Za-z]):\\(.*)"
    
    Pattern pattern = Pattern.compile( regex );
    Matcher matcher = pattern.matcher( path );
    if ( matcher.matches()) {
        System.out.println( "This path is on drive " + matcher.group( 1 ) + ":.");
        // This path is on drive C:.
    }

Если вы хотите совместить две обратные косые черты, вы обнаружите, что используете восьмеричную строку, чтобы представить четыре в регулярном выражении, чтобы соответствовать двум.

    String path = "\\\\myhost\\share\\myfile.txt";
    System.out.println( "UNC path: " + path ); // \\myhost\share\myfile.txt"
    
    String regex = "\\\\\\\\(.+?)\\\\(.*)"; // Eight to match two
    System.out.println("Regex:    " + regex ); // \\\\(.+?)\\(.*) 
    
    Pattern pattern = Pattern.compile( regex );
    Matcher matcher = pattern.matcher( path );
    
    if ( matcher.matches()) {
        System.out.println( "This path is on host '" + matcher.group( 1 ) + "'.");
        // This path is on host 'myhost'.
    }


Modified text is an extract of the original Stack Overflow Documentation
Лицензировано согласно CC BY-SA 3.0
Не связан с Stack Overflow