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


108

我正在尝试创建一个应用程序,该应用程序将消息模板与用户尝试发送的消息进行匹配。我正在使用Java正则表达式来匹配消息。模板/消息可能包含特殊字符。

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

是否有通用的解决方案可以在Java正则表达式中转义所有特殊字符?

Answers:


94

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

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

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


43
如果您很难记住\ Q和\ E,则可以改用Pattern.quote(“ ...”)
mkdev

19
我希望你居然说他们
亚历山大·杜宾斯基

为什么@AleksandrDubinsky?
索林2014年

55
@Sorin因为Stack Exchange的精神(不,政策?)是在您的答案中陈述答案,而不仅仅是链接到异地资源。此外,该页面也没有明确的列表。可以在此处找到列表:docs.oracle.com/javase/tutorial/essential/regex/literals.html,但它指出“在某些情况下,上面列出的特殊字符将被视为元字符,”而没有说明会发生什么情况。如果有人试图逃脱。简而言之,这个问题值得一个很好的答案。
Aleksandr Dubinsky 2014年

8
“ [ \Q\E] 之间的所有内容都被认为是转义的” –其他\Q的和除外\E(可能在原始正则表达式中发生)。因此,最好Pattern.quote按照此处的建议使用,而不要重新发明轮子。
萨沙

92
  • 必须在正则表达式中转义的Java字符是:
    \.[]{}()<>*+-=!?^$|
  • 仅在打开相同类型的支架后才需要放开两个闭合支架(]})。
  • []括号中,某些字符(如+-)有时可以正常运行而不会转义。

有什么办法可以逃脱却允许那些角色?
多米尼加

1
转义字符意味着允许字符而不是将其解释为运算符。
Tobi G.

4
非转义-[]可能并不总是可行的,因为它是用来定义范围。逃避它更安全。例如,模式[-][-)]匹配字符串,-但不匹配[(-)]
肯斯顿·崔

1
即使已接受的答案确实回答了问题,但当我只是在寻找快速列表时,此答案对我还是有帮助的。
老尼克

-=!不一定需要进行转义,这取决于上下文。例如,作为单个字母,它们可以用作常量正则表达式。
霍克

29

为了逃脱,您可以从Java 1.5使用它:

Pattern.quote("$test");

你会完全匹配单词 $test


为什么这不是评价最高的答案?它解决了该问题,而无需列出列出所有需要转义的字符的复杂细节,并且它是JDK的一部分-无需编写任何额外的代码!简单!
Volksman

17

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

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

在代码中的某个地方引用该列表也很酷,但是我不知道那在哪里...


11
String escaped = tnk.replaceAll("[\\<\\(\\[\\{\\\\\\^\\-\\=\\$\\!\\|\\]\\}\\)\\?\\*\\+\\.\\>]", "\\\\$0");
marbel82 '16

1
Pattern javadoc表示,在任何不表示转义构造的字母字符之前使用反斜杠是错误的,但是可以在非字母字符之前使用反斜杠,不管该字符是否是未转义构造的一部分。因此,一个简单得多的正则表达式就足够了:s.replaceAll("[\\W]", "\\\\$0")其中\W指定非单词字符。
乔·鲍比

6

结合每个人的讲话,我提出以下建议,以使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");
}

5

根据@Sorin对Java Pattern文档的建议,看起来至少要转义的字符是:

\.[{(*+?^$|

4
String escaped = regexString.replaceAll("([\\\\\\.\\[\\{\\(\\*\\+\\?\\^\\$\\|])", "\\\\$1");
fracz 2014年

2
)还必须转义,并且取决于您位于字符类的内部还是外部,可以有更多的字符要转义,在这种情况下Pattern.quote,转义字符串以供在字符类的内部和外部使用都做得很好。
nhahtdh 2015年

3

Pattern.quote(String s)那种你想要做什么。但是,它还有一点不足。它实际上并不会转义单个字符,而只是使用来包装字符串\Q...\E

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

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

为什么这样做?好吧,Pattern专门针对的文档说,它允许转义不一定要转义的非字母字符:

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

例如,;在正则表达式中不是特殊字符。但是,如果您Pattern将其转义,仍将解释\;;。以下是一些示例:

  • >变成\>等于>
  • [成为\[哪个是逃脱形式[
  • 8还是8
  • \)成为\\\)的转义形式\并将其(连接起来。

注意:关键是“非字母”的定义,它在文档中实际上表示“非单词 ”字符或字符集之外的字符[a-zA-Z_0-9]


2

在硬币的另一侧,如果特殊字符=应用程序上下文中的allChars-数字-ABC-空间,则应使用如下所示的“ non-char”正则表达式。

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

2

虽然答案是针对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


1

假设您拥有并信任(具有权威性)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);
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.