Java中的Regex Dark Corners ...字符的顺序改变了正则表达式的含义?

时间:2011-09-12 11:10:21

标签: java regex

我最近遇到了一些涉及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)方法,如列出的here

我的问题是......是否有人对于为什么放置空间会改变这个正则表达式的含义有什么好的技术想法?这真的没关系。

[EDITED] 从评论和答案 - 这是一个使用内置String方法导致不捕获的错误行为的示例。我的运行时环境根本没有抱怨,即使您阅读String.replaceAll(String, String)上的文档,它也明确指出它与Pattern.compile(regex).matcher(str).replaceAll(repl)具有相同的功能我想我会提交错误。

1 个答案:

答案 0 :(得分:9)

您使用了错误的转义字符,它是\而不是/

此外,我不确定您是否希望自己的字符组包含/.,或者您是否认为.需要在字符组中进行转义(它不会'需要进行转义:它始终代表字符组中的文字.

尝试编译[^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,_/.@,{{1 }或),后跟斜杠/,后跟<编译失败,因为格式错误>“。

你想要的可能是/,这是“与az,AZ,0-9,[^a-zA-Z0-9_.@ \]\[]_.,{{1}不匹配的字符},@“。

如果你用]字面值写,请记住加倍[(因为它们在String文字中也有特殊含义!):

\