Regex Dark Corners в Java ... порядок символов изменяет значение regex? - PullRequest
0 голосов
/ 12 сентября 2011

Недавно я столкнулся с каким-то странным поведением, связанным с движком Java для регулярных выражений.

При написании проверки мне нужно было добавить квадратные скобки в мое регулярное выражение, например:

"[^a-zA-Z0-9_/.@ ]"  // original expression
"[^a-zA-Z0-9_/.@ /]/[]"  // first modificiation

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

"[^a-zA-Z0-9_/.@/]/[ ]"  // final working modification

Теперь вызывающий код, который использовал это выражение, использовал метод String.replaceAll(String, String), как указано здесь .

У меня вопрос: есть ли у кого-нибудь хорошая техническая идея о том, почему размещение пространства меняет смысл этого регулярного выражения? Это действительно не должно иметь значения.

[Изменено] Из комментариев и ответов - это пример, где использование встроенного метода String приводит к некорректному поведению, которое НЕ улавливается. Моя среда выполнения НЕ ЖЕЛАЕТ вообще, даже если вы читаете документацию по String.replaceAll(String, String), в ней четко указано, что это та же функциональность, что и Pattern.compile(regex).matcher(str).replaceAll(repl). Я думаю, что сообщу об ошибке.

1 Ответ

9 голосов
/ 12 сентября 2011

Вы используете неправильный экранирующий символ, это \, а не /.

Кроме того, я не уверен, хотите ли вы, чтобы ваша группа персонажей включала / и . или есливы думали, что . необходимо экранировать в группах символов (экранировать его не нужно: оно всегда представляет литерал . в группах символов).

При попытке скомпилировать [^a-zA-Z0-9_/.@ /]/[]дает следующее исключение:

java.util.regex.PatternSyntaxException: Unclosed character class near index 20
[^a-zA-Z0-9_/.@ /]/[]
                    ^
    at java.util.regex.Pattern.error(Pattern.java:1713)
    at java.util.regex.Pattern.clazz(Pattern.java:2254)
    at java.util.regex.Pattern.sequence(Pattern.java:1818)
    at java.util.regex.Pattern.expr(Pattern.java:1752)
    at java.util.regex.Pattern.compile(Pattern.java:1460)
    at java.util.regex.Pattern.(Pattern.java:1133)
    at java.util.regex.Pattern.compile(Pattern.java:823)

Это указывает на наличие проблемы с классом символов в этой точке.И на самом деле: у вас есть пустой класс символов [], который недопустим!

[^a-zA-Z0-9_/.@ /]/[] означает «символ не соответствует» (az, AZ, 0-9, _, /, ., @, или /), затем косая черта /, за которой следует".

То, что вы хотите, это, вероятно, [^a-zA-Z0-9_.@ \]\[], который является" символом, не соответствующим az, AZ, 0-9, _, ., @, , ]или [ ".

Если вы пишете это в литерале String, не забудьте удвоить \ (потому что они также имеют особые значения в литералах String!):

Pattern regex = Pattern.compile("[^a-zA-Z0-9_.@ \\]\\[]");
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...