答案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
的替代方法可以转义单个文字而不是整个字符串?
答案 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