我正在尝试创建一个应用程序,该应用程序将消息模板与用户试图发送的消息相匹配。我使用 Javaregex 来匹配消息。模板/消息可能包含特殊字符。
如何获得需要转义的特殊字符的完整列表,以便在最大可能的情况下使用正则表达式并进行匹配?
在 Javaregex 中是否有转义所有特殊字符的通用解决方案?
另一方面,如果在应用程序上下文中使用特殊字符 = 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 1.5中的这个来逃避:
Pattern.quote("$test");
您将精确匹配字 $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包装字符串。
Pattern.quote(String s)
\Q...\E
没有一个方法可以完全满足您的需要,但好消息是,转义 Java 正则表达式中的所有特殊字符实际上相当简单:
regex.replaceAll("[\\W]", "\\\\$0")
为什么会这样?好吧,Pattern的文档特别说明它允许转义不一定要转义的非字母字符:
Pattern
在没有表示转义结构的任何字母字符之前使用反斜杠是错误的; 这些反斜杠是为将来正则表达式语言的扩展保留的。反斜杠可以在非字母字符之前使用,而不管该字符是否是未转义结构的一部分。
例如,;不是正则表达式中的特殊字符。但是,如果您转义它,Pattern仍将 \;解释为 ;。这里还有一些例子:
;
\;
>
\>
[
\[
8
\)
\\\)
\
(
注意: 关键是“非字母”的定义,在文档中,这实际上意味着“非 字”字符,或字符集 [a-zA-Z_0-9]之外的字符。
[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