需要在正则表达式中转义的所有特殊字符的列表

我正在尝试创建一个应用程序,该应用程序将消息模板与用户试图发送的消息相匹配。我使用 Javaregex 来匹配消息。模板/消息可能包含特殊字符。

如何获得需要转义的特殊字符的完整列表,以便在最大可能的情况下使用正则表达式并进行匹配?

在 Javaregex 中是否有转义所有特殊字符的通用解决方案?

392463 次浏览

另一方面,如果在应用程序上下文中使用特殊字符 = allChars-number-ABC-space,那么应该使用“ non-char”regex,它看起来像这样。

String regepx = "[^\\s\\w]*";

您可以查看 Pattern 类的 javadoc: http://docs.oracle.com/javase/8/docs/api/java/util/regex/Pattern.html

如果您想要的是正则字符而不是特殊含义,那么您需要转义那里列出的任何字符。

作为一个可能更简单的解决方案,您可以将模板放在 Q 和 E 之间——它们之间的所有内容都被认为是转义的。

根据@Sorin 对 Java 模式文档的建议,字符转义至少应该是:

\.[{(*+?^$|
  • 必须在正则表达式中转义的 Java 字符有:
    \.[]{}()<>*+-=!?^$|
  • 只有在打开相同类型的括号后,才需要转义两个闭括号(]})。
  • []-括号中,一些字符(如 +-)有时不带转义符就可以工作。

根据 字符串字面值/元字符文档页面,它们是:

<([{\^-=$!|]})?*+.>

另外,如果能在代码中引用这个列表,那也很酷,但我不知道它可能在哪里... ..。

你可以使用 Java 1.5中的这个来逃避:

Pattern.quote("$test");

您将精确匹配字 $test

综合所有人的观点,我建议使用以下方法,将 RegExp 特有的字符列表清楚地列在它们自己的 String 中,并避免尝试直观地解析成千上万个“”。这似乎对我很有效:

final String regExSpecialChars = "<([{\\^-=$!|]})?*+.>";
final String regExSpecialCharsRE = regExSpecialChars.replaceAll( ".", "\\\\$0");
final Pattern reCharsREP = Pattern.compile( "[" + regExSpecialCharsRE + "]");


String quoteRegExSpecialChars( String s)
{
Matcher m = reCharsREP.matcher( s);
return m.replaceAll( "\\\\$0");
}

Pattern.quote(String s)可以做你想做的事情。然而,它留下了一些需要改进的地方; 它实际上并不转义单个字符,只是用 \Q...\E包装字符串。

没有一个方法可以完全满足您的需要,但好消息是,转义 Java 正则表达式中的所有特殊字符实际上相当简单:

regex.replaceAll("[\\W]", "\\\\$0")

为什么会这样?好吧,Pattern的文档特别说明它允许转义不一定要转义的非字母字符:

在没有表示转义结构的任何字母字符之前使用反斜杠是错误的; 这些反斜杠是为将来正则表达式语言的扩展保留的。反斜杠可以在非字母字符之前使用,而不管该字符是否是未转义结构的一部分。

例如,;不是正则表达式中的特殊字符。但是,如果您转义它,Pattern仍将 \;解释为 ;。这里还有一些例子:

  • >变成等价于 >\>
  • [变成 \[,这是 [的转义形式
  • 还是 8
  • \)变成 \\\),这是 \(连接的转义形式。

注意: 关键是“非字母”的定义,在文档中,这实际上意味着“非 ”字符,或字符集 [a-zA-Z_0-9]之外的字符。

假设您拥有并且信任 Java regex 使用的转义字符列表(如果这些字符在某个 Pattern 类成员中公开就好了) ,如果确实需要的话,您可以使用以下方法来转义字符:

private static final char[] escapeChars = { '<', '(', '[', '{', '\\', '^', '-', '=', '$', '!', '|', ']', '}', ')', '?', '*', '+', '.', '>' };


private static String regexEscape(char character) {
for (char escapeChar : escapeChars) {
if (character == escapeChar) {
return "\\" + character;
}
}
return String.valueOf(character);
}

虽然答案是 Java,但是代码可以很容易地从我提出的 Kotlin String 扩展中改编(改编自提供的@brcolow) :

private val escapeChars = charArrayOf(
'<',
'(',
'[',
'{',
'\\',
'^',
'-',
'=',
'$',
'!',
'|',
']',
'}',
')',
'?',
'*',
'+',
'.',
'>'
)


fun String.escapePattern(): String {
return this.fold("") {
acc, chr ->
acc + if (escapeChars.contains(chr)) "\\$chr" else "$chr"
}
}


fun main() {
println("(.*)".escapePattern())
}

指纹 \(\.\*\)

检查它的行动在这里 https://pl.kotl.in/h-3mXZkNE