Как избежать квадратной скобки для компиляции шаблона?

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

.{8},[0-9],[^0-9A-Za-z ],[A-Z],[a-z]

Я сделал разделение запятой. Теперь я пытаюсь сопоставить это регулярное выражение с сгенерированным паролем. Проблема в том, что Pattern.compile не любит квадратные скобки, которые не экранированы.

Кто-нибудь, пожалуйста, дайте мне простую функцию, которая берет такую ​​строку: [0-9] и возвращает экранированную строку \[0-9\].


person Afamee    schedule 16.07.2009    source источник


Ответы (4)


Вы можете использовать Pattern.quote(String).

Из документов:

public static String quote​(String s)

Возвращает буквенный шаблон String для указанного String.

Этот метод создает строку, которую можно использовать для создания шаблона, который будет соответствовать строке s, как если бы это был буквальный шаблон.

Метасимволы или управляющие последовательности во входной последовательности не будут иметь специального значения.

person Laurence Gonsalves    schedule 16.07.2009
comment
Какое значение вы вставляете для String? Pattern.quote("\[0-9\]")? - person Danny Bullis; 11.04.2018
comment
@DannyBullis Из вопроса простая функция, которая принимает такую ​​строку: [0-9] и возвращает экранированную строку \[0-9\]. Таким образом, вы бы передали этому "[0-9]", и он вернет что-то эквивалентное "\[0-9\]". (На самом деле он использует \Q и \E, но конечный результат имеет тот же эффект, что и Pattern.compile.) - person Laurence Gonsalves; 11.04.2018
comment
Потрясающие. Спасибо за быструю помощь, даже спустя 9 лет :) - person Danny Bullis; 11.04.2018

По какой-то причине приведенный выше ответ не сработал для меня. Для таких, как я, кто придет после, вот что я нашел.

Я ожидал, что одна обратная косая черта выйдет из скобки, однако вы должны использовать две, если у вас есть шаблон, сохраненный в строке. Первая обратная косая черта экранирует вторую в строке, так что регулярное выражение видит \]. Поскольку регулярное выражение видит только одну обратную косую черту, оно использует ее для выхода из квадратной скобки.

\\] 

В регулярном выражении это будет соответствовать одной закрывающей квадратной скобке.

Если вы пытаетесь сопоставить новую строку, например, вы должны использовать только одну обратную косую черту. Вы используете шаблон экранирования строки для вставки символа новой строки в строку. Regex не видит \n - он видит символ новой строки и соответствует ему. Вам нужны две обратные косые черты, потому что это не escape-последовательность строки, это escape-последовательность регулярного выражения.

person Cullub    schedule 29.07.2015
comment
Подумав об этом, я понял, почему это так: регулярное выражение представляет собой строку, и все, что обрабатывает это регулярное выражение, будет искать одну обратную косую черту в качестве escape-символа. Однако, поскольку регулярное выражение передается как строка, вам также необходимо избежать обратной косой черты, чтобы правильно преобразовать ее в строку, и это чтение, почему вам нужны две обратные косые черты - person Raven; 27.03.2016

Вы можете использовать специальные символы \Q и \E... все символы между \Q и \E автоматически экранируются.

\Q[0-9]\E
person Dan Breen    schedule 16.07.2009
comment
Звучит немного ужасно, если вы спросите меня, пробовали ли вы это в java (я не пробовал, поэтому и спрашиваю). - person Fredrik; 18.07.2009
comment
Это допустимо и для Java: java.sun. com/javase/6/docs/api/java/util/regex/Pattern.html (ctrl-F для \Q) - person MatrixFrog; 18.07.2009
comment
В формате строкового литерала Java это будет \\Q[0-9]\\E или \\Q + regex + \\E. Но метод quote() сделает это за вас, а также правильно обработает строки, в которых уже есть \E. - person Alan Moore; 19.07.2009

Pattern.compile() очень любит квадратные скобки. Если взять строку

".{8},[0-9],[^0-9A-Za-z ],[A-Z],[a-z]"

и разделить его на запятые, вы получите пять абсолютно правильных регулярных выражений: первое соответствует восьми символам без разделителя строк, второе соответствует цифре ASCII и так далее. Если вы действительно не хотите сопоставлять такие строки, как ".{8}" и "[0-9]", я не понимаю, почему вам нужно что-то экранировать.

person Alan Moore    schedule 18.07.2009