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

Posted

技术标签:

【中文标题】需要在正则表达式中转义的所有特殊字符的列表【英文标题】:List of all special characters that need to be escaped in a regex 【发布时间】:2012-12-17 13:24:14 【问题描述】:

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

如何获得需要转义的特殊字符的完整列表,以便我的正则表达式在尽可能多的情况下工作和匹配?

有没有通用的解决方案来转义 Java 正则表达式中的所有特殊字符?

【问题讨论】:

【参考方案1】:

虽然答案是针对 Java 的,但是代码可以很容易地从我想出的这个 Kotlin 字符串扩展中改编(改编自 @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

【讨论】:

为我节省了一些时间,谢谢!【参考方案2】:

假设您拥有并信任(具有权威性)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);

【讨论】:

【参考方案3】:

Pattern.quote(String s) 可以满足您的需求。然而,它还有一些不足之处。它实际上并没有转义单个字符,只是用\Q...\E 包装字符串。

没有一种方法完全符合您的要求,但好消息是,在 Java 正则表达式中转义所有特殊字符实际上相当简单:

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

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

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

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

&gt; 变为 \&gt; 相当于 &gt; [ 变为 \[,这是 [ 的转义形式 8 仍然是 8\) 变为 \\\),这是 \( 连接的转义形式。

注意:关键是“非字母”的定义,在文档中真正的意思是“非单词”字符,或者字符之外的字符设置[a-zA-Z_0-9]

【讨论】:

【参考方案4】: 必须在正则表达式中转义的 Java 字符有:\.[]()&lt;&gt;*+-=!?^$| 两个右括号(])只需要在打开相同类型的括号后进行转义。 在[]-brackets 中,某些字符(如+-)有时会在没有转义的情况下工作。

【讨论】:

有什么方法可以不转义但允许这些字符? 转义字符意味着允许该字符而不是将其解释为运算符。 [] 中未转义的- 可能并不总是有效,因为它用于定义范围。逃避它更安全。例如,模式[-][-)] 匹配字符串-,但不匹配[(-)] 尽管接受的答案确实回答了这个问题,但当我只是在寻找一个快速列表时,这个答案对我更有帮助。 -=! 不一定需要转义,这取决于上下文。例如,作为单个字母,它们作为常量正则表达式工作。【参考方案5】:

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

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

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

【讨论】:

如果你觉得 \Q 和 \E 很难记住,你可以使用 Pattern.quote("...") 我希望你真的说出来了 为什么,@AleksandrDubinsky ? @Sorin 因为 Stack Exchange 的精神(不,政策?)在您的答案中陈述答案,而不仅仅是链接到场外资源。此外,该页面也没有明确的列表。可以在此处找到一个列表:docs.oracle.com/javase/tutorial/essential/regex/literals.html,但它声明“在某些情况下,上面列出的特殊字符将 被视为元字符”,但没有解释如果试图逃避它们会发生什么。总之,这个问题值得很好的回答。 “它们之间的所有内容 [\Q\E] 都被视为已转义” - 除了其他 \Q\E (可能可能发生在原始正则表达式中)。所以,最好按照here 的建议使用Pattern.quote,而不是重新发明***。【参考方案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");

【讨论】:

【参考方案7】:

根据String Literals / Metacharacters 文档页面,它们是:

&lt;([\^-=$!|])?*+.&gt;

另外,在代码中的某个地方引用该列表会很酷,但我不知道它可能在哪里......

【讨论】:

String escaped = tnk.replaceAll("[\\&lt;\\(\\[\\\\\\\\^\\-\\=\\$\\!\\|\\]\\\\)\\?\\*\\+\\.\\&gt;]", "\\\\$0"); Pattern javadoc 说在任何不表示转义结构的字母字符之前使用反斜杠是错误的,但是可以在非转义之前使用反斜杠- 字母字符,无论该字符是否是未转义结构的一部分。因此,一个更简单的正则表达式就足够了:s.replaceAll("[\\W]", "\\\\$0") 其中\W 指定非单词字符。【参考方案8】:

为了逃避你可以从Java 1.5使用这个:

Pattern.quote("$test");

您将准确匹配单词$test

【讨论】:

为什么这不是评价最高的答案?它解决了这个问题,而无需详细列出所有需要转义的字符,它是 JDK 的一部分 - 无需编写任何额外的代码!简单! 如果一个正则表达式包含 \E 怎么办?怎么能逃脱?例如:“\\Q\\Eeee\\E”抛出 java.util.regex.PatternSyntaxException: Illegal/unsupported escape sequence near index 4【参考方案9】:

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

\.[(*+?^$|

【讨论】:

String escaped = regexString.replaceAll("([\\\\\\.\\[\\\\(\\*\\+\\?\\^\\$\\|])", "\\\\$1"); ) 也必须被转义,并且取决于您是在字符类内部还是外部,可以有更多字符需要转义,在这种情况下 Pattern.quote 做得很好在转义字符串以在字符类内部和外部使用。【参考方案10】:

另一方面,如果特殊字符 = allChars - 数字 - ABC - 应用上下文中的空格,则应使用如下所示的“非字符”正则表达式。

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

【讨论】:

以上是关于需要在正则表达式中转义的所有特殊字符的列表的主要内容,如果未能解决你的问题,请参考以下文章

在正则表达式中转义特殊字符

你如何在 Freemarker 中转义正则表达式字符串

从 glob 表达式创建正则表达式

正则表达式从字符串中删除所有特殊字符?

正则表达式--python(表示字符)

我必须在 Perl 预编译的正则表达式中转义哪些字符?