转义正则表达式字符串中的每个文字,而不是引用整个字符串

时间:2015-03-26 10:44:05

标签: java regex string escaping

答案here建议使用Pattern.quote以逃避特殊的正则表达式字符。

Pattern.quote的问题在于它是整个字符串的转义,而不是每个特殊字符。

这是我的情况:
我从用户收到一个字符串,需要在文档中搜索它。 由于用户无法传递新行字符(这是我无法访问的第三方API中的错误),我决定将任何空格序列视为“\ s +”并使用正则表达式搜索文档。这样,用户可以发送简单的空格而不是换行符。

例如,如果文件是:

  

\ s元字符用于查找空白字符。

     

空格字符可以是:
  

  • 空格字符
      
  • 标签字符
      
  • 回车符   
  • 换行符号   
  • 垂直制表符字符
      
  • 换页符

  • 然后收到的字符串

    String receivedStr = "The \s metacharacter is used to find a whitespace character. A whitespace character can be:";
    

    应该在文件中找到。

    为了实现这一点,我想引用字符串,然后用字符串“\ s +”替换任何空格序列。
    使用以下代码:

    receivedStr = Pattern.quote(receivedStr).replaceAll("\\s+", "\\\\s+");
    

    产生正则表达式:

      

    \ QThe \ S + \ S \ S +元字符\ S +被\ S +使用\ S +到\ S +找到\ S + A \ S +空白\ S +字符。\ S + A \ S +空白\ S +字符\ S +可以\ S +是:。\ E

    当然会忽略我添加的"\s+"而不是预期的:

      

    在\ S + \\小号\ S +元字符\ S +是\ S +使用\ S +到\ S +找到\ S + A \ S +空白\ S +字符。\ S + A \ S +空白\ S +字符\ S +可以\ S +是:

    只能转义“\ s”文字,而不是整个字符串。

    是否有Pattern.quote的替代方法可以转义单个文字而不是整个字符串?

    1 个答案:

    答案 0 :(得分:2)

    我会建议这样的事情:

    String re = Stream.of(input.split("\\s+"))
                      .map(Pattern::quote)
                      .collect(Collectors.joining("\\s+"));
    

    这样可以确保所有内容都被引用(包括原本会被解释为环视并且可能导致匹配查找的指数爆炸),任何输入空格的用户最终都会被视为不引用\s+

    示例输入:

    Lorem \\b ipsum \\s dolor (sit) amet.
    

    <强>输出:

    \QLorem\E\s+\Q\b\E\s+\Qipsum\E\s+\Q\s\E\s+\Qdolor\E\s+\Q(sit)\E\s+\Qamet.\E