Как экранировать текст для регулярного выражения в Java

java regex escaping

207035 просмотра

8 ответа

Есть ли в Java встроенный способ экранирования произвольного текста, чтобы его можно было включить в регулярное выражение? Например, если мои пользователи введут «5 долларов», я бы хотел, чтобы это совпадало, а не 5 после окончания ввода.

Автор: Matt Источник Размещён: 29.07.2019 04:08

Ответы (8)


426 плюса

Решение

Начиная с Java 1.5, да :

Pattern.quote("$5");
Автор: Mike Stone Размещён: 12.09.2008 11:39

102 плюса

Разница между Pattern.quoteи Matcher.quoteReplacementне была мне понятна до того, как я увидел следующий пример

s.replaceFirst(Pattern.quote("text to replace"), 
               Matcher.quoteReplacement("replacement text"));
Автор: Pavel Feldman Размещён: 12.09.2008 11:52

26 плюса

Возможно, будет слишком поздно для ответа, но вы также можете использовать Pattern.LITERAL, что будет игнорировать все специальные символы при форматировании:

Pattern.compile(textToFormat, Pattern.LITERAL);
Автор: Androidme Размещён: 14.03.2016 03:04

13 плюса

Я думаю, что вы после этого \Q$5\E. Также см. Pattern.quote(s)Введенный в Java5.

См. Шаблон Javadoc для деталей.

Автор: Rob Oxspring Размещён: 12.09.2008 11:42

10 плюса

Во-первых, если

  • вы используете replaceAll ()
  • Вы НЕ используете Matcher.quoteReplacement ()
  • текст, который будет заменен, включает в себя $ 1

это не ставит 1 в конце. Он будет смотреть на регулярное выражение поиска для первой подходящей группы и подпункта THAT. Вот что означает $ 1, $ 2 или $ 3 в замещающем тексте: сопоставление групп из шаблона поиска.

Я часто вставляю длинные строки текста в файлы .properties, а затем генерирую из них темы и сообщения электронной почты. Действительно, это, кажется, способ сделать i18n по умолчанию в Spring Framework по умолчанию. Я помещаю теги XML в качестве заполнителей в строки и использую replaceAll () для замены тегов XML значениями во время выполнения.

Я столкнулся с проблемой, когда пользователь вводил цифру в долларах и центах со знаком доллара. replaceAll () захлебнулся, и в следовой строке появилось следующее:

java.lang.IndexOutOfBoundsException: No group 3
at java.util.regex.Matcher.start(Matcher.java:374)
at java.util.regex.Matcher.appendReplacement(Matcher.java:748)
at java.util.regex.Matcher.replaceAll(Matcher.java:823)
at java.lang.String.replaceAll(String.java:2201)

В этом случае пользователь ввел «$ 3» где-то в своем вводе, а replaceAll () пошёл искать в регулярном выражении поиска третью подходящую группу, не нашел ни одной и рванул.

Дано:

// "msg" is a string from a .properties file, containing "<userInput />" among other tags
// "userInput" is a String containing the user's input

замена

msg = msg.replaceAll("<userInput \\/>", userInput);

с

msg = msg.replaceAll("<userInput \\/>", Matcher.quoteReplacement(userInput));

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

Автор: Meower68 Размещён: 14.08.2012 03:00

6 плюса

Чтобы иметь защищенный шаблон, вы можете заменить все символы на «\\\\», кроме цифр и букв. И после этого вы можете вставить в этот защищенный шаблон ваши специальные символы, чтобы этот шаблон работал не как глупый цитируемый текст, а как паттерн, но как ваш собственный. Без специальных символов пользователя.

public class Test {
    public static void main(String[] args) {
        String str = "y z (111)";
        String p1 = "x x (111)";
        String p2 = ".* .* \\(111\\)";

        p1 = escapeRE(p1);

        p1 = p1.replace("x", ".*");

        System.out.println( p1 + "-->" + str.matches(p1) ); 
            //.*\ .*\ \(111\)-->true
        System.out.println( p2 + "-->" + str.matches(p2) ); 
            //.* .* \(111\)-->true
    }

    public static String escapeRE(String str) {
        //Pattern escaper = Pattern.compile("([^a-zA-z0-9])");
        //return escaper.matcher(str).replaceAll("\\\\$1");
        return str.replaceAll("([^a-zA-Z0-9])", "\\\\$1");
    }
}
Автор: Moscow Boy Размещён: 15.11.2012 08:27

3 плюса

Pattern.quote ("Blabla") работает хорошо.

Pattern.quote () работает хорошо. Он включает в себя предложение с символами « \ Q » и « \ E », и, если он экранирует «\ Q» и «\ E». Однако, если вам нужно сделать реальное экранирование регулярного выражения (или пользовательское экранирование), вы можете использовать этот код:

String someText = "Some/s/wText*/,**";
System.out.println(someText.replaceAll("[-\\[\\]{}()*+?.,\\\\\\\\^$|#\\\\s]", "\\\\$0"));

Этот метод возвращает: Some / \ s / wText * / \, **

Код для примера и тесты:

String someText = "Some\\E/s/wText*/,**";
System.out.println("Pattern.quote: "+ Pattern.quote(someText));
System.out.println("Full escape: "+someText.replaceAll("[-\\[\\]{}()*+?.,\\\\\\\\^$|#\\\\s]", "\\\\$0"));
Автор: Adam111p Размещён: 31.07.2017 12:26

-1 плюса

Символ ^ (Отрицание) используется для сопоставления чего-либо, чего нет в группе символов.

Это ссылка на регулярные выражения

Вот информация об изображении об отрицании:

Информация об отрицании

Автор: Akhil Kathi Размещён: 22.06.2018 03:00
Вопросы из категории :
32x32