Рубрики
Без рубрики

ВВЕДЕНИЕ В РЕГУЛЯРНЫЕ ВЫРАЖЕНИЯ ДЛЯ РАЗРАБОТЧИКОВ JAVA

Согласно oracle doc, регулярные выражения, обычно называемые регулярными выражениями, являются способами описания набора s… С пометкой java, codenewbie, учебник, новички.

Согласно oracle doc , Регулярные выражения, обычно называемые регулярными выражениями, представляют собой способы описания набора строк на основе общих характеристик, общих для каждой строки в наборе. Их можно использовать для поиска, редактирования или манипулирования текстом и данными.

С точки зрения непрофессионала, регулярные выражения – это способы, которые помогают вам проверять или сопоставлять строки в соответствии с определенным форматом. Другими словами, вы можете использовать его для проверки правильности конкретного ввода пользователем или использовать его для извлечения или извлечения значений, соответствующих определенной последовательности.

ВАЖНОСТЬ/ИСПОЛЬЗОВАНИЕ РЕГУЛЯРНЫХ ВЫРАЖЕНИЙ • Проверка введенных пользователем данных. • Поиск текста в заданных данных. (может использоваться в текстовых редакторах) • Синтаксический анализатор в компиляторах • Подсветка синтаксиса, анализаторы пакетов и т.д.

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

КВАНТОРЫ ( * + ? {n} . ) Кванторы в Java (и в большинстве языков программирования) состоят из , +, ?, {} . a) * соответствует нулю или более экземпляров предыдущего шаблона. например, abc * означает, что текст должен соответствовать “ab”, за которым следует ноль или более “c”, т.е. к тексту может не быть прикреплено “c”, и в тексте также может быть одно или несколько “c”. Предыдущий шаблон в этом случае – “ab”. * ПОПРОБУЙ ЭТО **

б) + соответствует одному или нескольким экземплярам предыдущего шаблона, например, abc + означает, что в тексте должно быть “ab”, за которым следует один или несколько “c”. таким образом, abc – это наименьшее, что у вас может быть правильным, abcc тоже правильный. ПОПРОБУЙ ЭТО

в) ? соответствует нулю или одному вхождению шаблона, например, abc? Означает, что текст может быть либо abc, либо ab. ПОПРОБУЙ ЭТО .

d) {n} соответствует точному числу (n), указанному в выражении. например, a {2} bc означает, что у вас может быть только два “a”, за которыми следует один “b” и один “c”. ПОПРОБУЙ ЭТО

e) {n, } соответствует, по крайней мере, указанному номеру. Это означает, что у вас должно быть n или более чисел предыдущего выражения, например, ab {2,} c означает, что у вас должно быть a, за которым следуют два или более “b”, а затем c. ПОПРОБУЙТЕ

f) {n,m} совпадения между n и m (включительно) шаблона. Это означает, что у вас может быть между двумя вхождениями предыдущего шаблона. например, ab {2,5}c означает, что abbc, abbbc, abbbc, abbbbc все правильные. Все, что из этого вышло, неправильно. ПОПРОБУЙ ЭТО .

g) ‘.’ соответствует всем символам без пробелов

ОПЕРАТОРЫ(| [] ^ ) Труба (|) используется как “ИЛИ”. Таким образом, оно соответствует выражению слева или выражению справа. например, abc | abd означает, что текст должен быть либо abc, либо abd. ПОПРОБУЙ ЭТО .

[] [] [] [] означает, что текст должен соответствовать любому из символов в угловых скобках, например, a [bc] означает, что текст должен быть “a”, за которым следует “b” или “c”. [0-9]% означает, что текст должен содержать любое число от 0 до 9, за которым следует “%” [a-zA-Z] означает любой символ, если он находится между a-z или A-Z. [abc] означает, что текст или строка должны быть либо a, либо b, либо c. Добавление ‘^’ к любому из выражений сводит на нет значение этого выражения, например, [^abc] означает, что строка должна быть любым символом, если это не a, b или c. ПОПРОБУЙТЕ .

ГРУППИРОВКА И ОБРАТНЫЕ ССЫЛКИ Еще одна интересная особенность регулярных выражений заключается в том, что вы можете группировать свои выражения и, возможно, повторно использовать их при необходимости. Для группировки элементов в выражениях используйте круглые скобки, например (). Обратная ссылка хранит часть строки, которая соответствовала группе. Вы можете ссылаться на определенную группу, используя знак $. $1, $ 2… представляют группу 1, группу 2 и т.д. группа по умолчанию равна $0, что является самим текстом. Например, давайте удалим все пробелы в предложении.Регулярным выражением для этого примера будет приведенный ниже фрагмент кода:

private static String backReference(String text) {
    String pattern = "(\\w+)([\\s])";
    return text.replaceAll(pattern, "$1");
}

Выражение в приведенном выше коде состоит из 2 групп: (\w+) и (\s). Итак, мы говорим, что текст должен состоять из набора слов (\w +) и пробелов (\s+). После этого мы заменим весь текст только группой 1 ($ 1), которая просто удалит пробелы, потому что все, что нам сейчас нужно, – это просто слова. Ссылка на 1 доллар в обратной ссылке.

записка: В java нам нужно экранировать класс символов (\w и \s) другой косой чертой, иначе у вас будет синтаксическая ошибка.

СМОТРИТЕ ВПЕРЕД/ОГЛЯНИСЬ НАЗАД Это способ исключить шаблон. Таким образом, вы можете сказать, что строка должна быть допустимой только в том случае, если она не предшествует определенной строке, и наоборот. например) будет соответствовать “abc” до тех пор, пока оно следует за “d”. но обратите внимание, что буква “d” будет исключена. ПОПРОБУЙ ЭТО . Хорошим применением этого в реальной жизни было бы получить значение в любом HTML-теге, например Hello World. Выражение будет (?i)()(.*(?=<))() ПОПРОБУЙТЕ . Это возвращает Привет, Мир Вы также можете использовать (?! шаблон) как отрицательный взгляд вперед, например, ab(?! c) будет соответствовать ab, если за “ab” не следует “b”.

ЖАДНЫЙ И ЛЕНИВЫЙ Вышеприведенные кванторы называются жадными в том смысле, что они будут соответствовать как можно большему количеству вхождений, пока совпадение все еще успешно. например, для регулярного выражения a. + c можно было бы ожидать, что это будет означать, что текст должен быть “a”, за которым следует один или несколько символов без пробелов. Таким образом, вы ожидаете, что возможное совпадение будет “abcccd” или “abcc” или “abbc” в качестве индивидуальных результатов. Это должно быть правдой, но из-за жадного отношения он захватит все тексты (abcccc abbc) как один и вернет ‘abcccd abcc abbc’ в качестве одного результата, потому что, если вы заметили, первым символом является ‘a’, за которым следует один или несколько любых других символов, и теперь он заканчивается c, который точно соответствует a. + c

Чтобы ограничить это “жадное отношение”, просто добавьте знак вопроса (?) перед квантором, это делает квантор немного неохотным, что означает, что он будет соответствовать как можно меньшему количеству вхождений, если совпадение будет успешным. Таким образом, ab.+? c возвращал бы результаты по отдельности вместо того, чтобы захватывать всю строку и обрабатывать их как одно целое. ПОПРОБУЙТЕ .

Лучшим применением этого было бы следующее: Предполагая, что вы хотите получить только теги и h1> отдельно от Привет, мир , вы ожидаете, что регулярное выражение для него будет <.+> h1> отдельно от Привет, мир , вы ожидаете, что регулярное выражение для него будет <.+> но на самом деле он собирается захватить весь текст ( Привет, мир h1>) и обработать его как один и все равно вернет вам тот же текст, потому что он фактически соответствует предоставленному вами выражению (текст должен начинаться с “<“, за которым следует один или несколько любых других символов, а затем заканчиваться “>” ), которому текст удовлетворяет ПОПРОБУЙТЕ . h1>) и обработать его как один и все равно вернет вам тот же текст, потому что он фактически соответствует предоставленному вами выражению (текст должен начинаться с “<“, за которым следует один или несколько любых других символов, а затем заканчиваться “>” ), которому текст удовлетворяет ПОПРОБУЙТЕ .

В двух словах, “Жадный” означает совпадение с максимально длинной строкой, в то время как “ленивый” означает совпадение с максимально короткой строкой.

ПРИМЕЧАНИЕ: Будьте осторожны при использовании этих кванторов, особенно точки(.) в выражениях.

КЛАССЫ ПЕРСОНАЖЕЙ Класс символов – это экранирующая последовательность, представляющая группу символов. Некоторые предопределенные символы в java перечислены ниже:

Если вы заметили из приведенной выше таблицы, прописные буквы сводят на нет функции строчных букв наоборот

ТЕПЕРЬ ПЕРЕЙДЕМ К МИРУ JAVA Класс String в Java поставляется со встроенным логическим методом matches, который сопоставляет строку с регулярным выражением.

public static void main(String[] args) {
    String value = "12345";
    System.out.println("The Result is: "+value.matches("\\d{5}"));
}

Приведенный выше фрагмент кода вернет “Результат: истина”, потому что значение (12345) соответствует ровно 5 символам. Все, что угодно, кроме 5, вернет “Результат: ложь”.

Помимо метода matches класса String, большинство классов, которые вам понадобятся для регулярных выражений, находятся в пакете java.util.regex. Они состоят из трех классов: • Шаблон : это скомпилированное представление регулярного выражения. Чтобы использовать это, вы должны сначала вызвать статический метод (compile) в классе pattern, который возвращает объект Pattern. • * Совпадения : Это механизм, который интерпретирует шаблон и выполняет операции сопоставления с входной строкой. Чтобы получить объект, вы должны вызвать метод matches для объекта шаблона. Исключение PatternSyntaxException

Для сопоставления строки с использованием классов шаблонов/сопоставителей

public static void main(String[] args) {
    String value = "12345";
    String regex = "\\d{5}";
    Pattern pattern = Pattern.compile(regex);
    Matcher matcher = pattern.matcher(value);
    System.out.println("The Result is: "+matcher.matches());
}

Теперь вопрос в том, зачем мне испытывать стресс от использования шаблона/сопоставления, когда я могу просто сопоставить строку с регулярным выражением (значение.совпадает(регулярное выражение)) . Ну, правда в том, что реализация метода совпадает в строке класса с использованием шаблона/сопоставления под капотом. Таким образом, для каждой строки, которую вы сопоставляете, он создает объект шаблона перед сопоставлением.

Когда использовать шаблон/сопоставитель ПРОТИВ строки.совпадения (текст строки)

public class PatternMatcher {
    public static void main(String[] args) {
        String [] texts = {"nozzle","punjabi","waterlogged","imprison","crux","numismatlogists","sultans","rambles","deprecating","aware","outfield","marlborough","guardrooms","roast","wattage","shortcuts","confidential","reprint","foxtrot","disposseslogsion","floodgate","unfriendliest","semimonthlies","dwellers","walkways","wastrels","dippers","engrlogossing","undertakings"};
         List resultStringMatches = matchUsingStringMatches(texts);
        List resultsPatternMatcher = matchUsingPatternMatcher(texts);
        System.out.println("The Result for String matches is: "+resultStringMatches.toString());
        System.out.println("The Result for pattern/matcher is: "+resultStringMatches.toString());
    }

    private static List matchUsingPatternMatcher(String[] texts) {
        List matchedList = new ArrayList<>();
        String pattern = "[a-zA-Z]*log[a-zA-Z]*";
        Pattern regexPattern = Pattern.compile(pattern);
        Matcher matcher;
        for (int i = 0; i < texts.length; i++) {
             matcher = regexPattern.matcher(texts[i]);
            if (matcher.matches()) {
                matchedList.add(texts[i]);
            }
        }
        return matchedList;
    }

    private static List matchUsingStringMatches(String[] texts) {
        String pattern = "[a-zA-Z]*log[a-zA-Z]*";
        List matchedList = new ArrayList<>();

        for (int i = 0; i < texts.length; i++) {
            //for each time it calls matches(pattern), it creates a pattern object
            if (texts[i].matches(pattern)) {
                matchedList.add(texts[i]);
            }
        }
        return matchedList;
    }
}

Приведенный выше код сопоставляет все элементы массива с определенным регулярным выражением ([a-Za-Z] log[a-Za-Z] ). Регулярное выражение предназначено для получения всех текстов, содержащих слово “журнал”. Перед сопоставлением с регулярным выражением это выражение должно быть скомпилировано (Pattern.compile); Первый метод сопоставление с использованием сопоставления шаблонов() сначала компилирует шаблон, прежде чем искать совпадения, в то время как второй метод matchUsingStringMatches() создает новый объект шаблона

(Шаблон.компиляция()) для каждого элемента в массиве, который является дорогостоящим/дорогостоящим и может привести к утечке памяти, особенно если данных/текстов слишком много. Поэтому, если вы заботитесь о производительности при работе с большим набором данных, сначала используйте класс Pattern/Matcher для компиляции и используйте экземпляр для сопоставления текстов.

Большое вам спасибо за чтение. Пожалуйста, вы можете оставить комментарий, предложение или исправление в разделе комментариев ниже.

Оригинал: “https://dev.to/codechunker/introduction-to-regex-expressions-for-java-developers-11jn”