Java正则表达式模式未关闭字符类

5

我需要一些帮助。我遇到了:

Caused by: java.util.regex.PatternSyntaxException: Unclosed character class near index 24
^[a-zA-Z└- 0-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.<init>(Pattern.java:1133)
        at java.util.regex.Pattern.compile(Pattern.java:823)

这是我的代码:
String testString = value.toString();

Pattern pattern = Pattern.compile("^[a-zA-Z\300-\3770-9\u0153\346 \u002F.'-\\]*$");
Matcher m = pattern.matcher(testString);

我必须使用Unicode值,因为我正在处理XHTML。
任何帮助都将不胜感激!
2个回答

23
假设你想匹配\-而不是]
Pattern pattern = Pattern.compile("^[a-zA-Z\300-\3770-9\u0153\346 \u002F.'\\\\-]*$");

你需要双重转义反斜杠,因为在正则表达式中\也是一个转义字符。因此\\]对于Java来说转义了反斜杠,但对于正则表达式不起作用。你需要再添加一个Java转义的\来对第二个Java转义的\进行正则表达式转义。

因此,Java转义后的\\\\变成\\,然后被正则表达式转义为\

-移到序列末尾意味着它被用作字符,而不是范围运算符,正如Pshemo所指出的。


我认为每个人都遇到了这个问题。我没有意识到我需要将 '' 倍增才能在我的正则表达式中实现反斜杠。我感谢大家的建议。 - Joseph Vance

2

很难说你想要实现什么,但我可以看到你的正则表达式中有几个奇怪的地方:

  1. 你打开了字符类但却没有关闭它。相反,你使用了\\]来使]成为普通字符。
    • 如果你想在字符类中包含],那么你需要在末尾加上额外的],像这样:"^[a-zA-Z\300-\3770-9\u0153\346 \u002F.'-\\]]*$"
    • 如果你想在字符类中包含\,那么你需要使用\\\\版本,因为你需要在正则表达式引擎和Java字符串中都转义它的特殊含义。
  2. 你使用了-(' -\\]')一起,在字符类中用于指定范围,如a-zA-Z. 要转义其特殊含义,你需要使用\\-

1
这段程序相关的内容是否可行:Pattern pattern = Pattern.compile("^[a-zA-Z\300-\3770-9\u0153\346 \u002F.'\\-\\\\]*$");?在Java字符串中书写反斜杠时需要四次转义。 - Jason Sperske
@JasonSperske 提到了一个好点子,如果 OP 想在字符类中包含 \,可以使用 \\\\] - Pshemo
@JasonSperske 如果你想把“-”作为一个字符包含进去,你可以把它放在末尾。如果字符类中没有任何内容跟在它后面,那么它就不会被视为运算符。 - Jeff
据我所知,将“-”放在字符类的开头或结尾对于Java来说是可行的,但这可能不是一个好的做法,因为并非所有语言/正则表达式引擎都接受这种使用方式。因此最好明确地转义其特殊含义。 - Pshemo
@Jeff 正确。我想把它包含进去,所以我把它放在最后。 - Joseph Vance
我不了解其他语言/正则表达式引擎,所以我得相信你说的话。另外,如果有人在它后面加上什么东西,代码就会变得难以维护,并且可能会导致非常微妙的错误,所以我认为你可能是对的。 - Jeff

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接