如何逃避所有正则表达式的特殊字符,但不是一次性(通过Pattern.quote()),只是一个一个

时间:2012-05-09 15:03:58

标签: java regex

问题在于:向用户显示一个文本字段,可以键入过滤器。过滤器,用于过滤未过滤的数据。遇到Oracle Forms洗脑的用户除了%之外没有任何特殊字符,我想这或多或少代表Java中的“。*”正则表达式。

如果用户表现良好,给定的人会输入类似“CTHULH%”的内容,在这种情况下我可以构建一个模式:

Pattern.compile(inputText.replaceAll("%", ".*"));

但是,如果用户人员来自Innsmouth,那么他会输入“。+ \ [a - #$%^& *(”用几个简单的击键来破坏我的方案。这不会起作用:

Pattern.compile(Pattern.quote(inputText).replaceAll("%", ".*"));

因为它会在开头放置\ Q,在字符串末尾放置\ E,渲染我的% - > 。*切换没有实际意义。

问题是:我是否必须在模式代码中查找每个特殊字符并通过在前面添加“\\”来自行转义,或者这可以自动完成吗?或者我是如此深入到这个问题,我忽略了一些明显的解决方法?

2 个答案:

答案 0 :(得分:6)

我认为这个算法适合你:

  • 拆分%
  • 使用Pattern.quote
  • 分别引用每个部分
  • 使用.*
  • 加入字符串

答案 1 :(得分:2)

Pattern.compile(Pattern.quote(inputText).replaceAll("%", "\\E.*\\Q"));怎么样?

这应该导致以下模式:

input:   ".+\[a-#$%^&*(" 
quote:   \Q".+\[a-#$%^&*("\E 
replace: \Q".+\[a-#$\E.*\Q^&*("\E

如果%字符是第一个或最后一个字符,您将获得\Q\E(如果您只有输入%,则表达式将最终为\Q\E.*\Q\E )但这应该仍然是一个有效的表达。

更新

我忘记了replace(...)replaceAll(...)之间的区别:前者中的替换参数是文字,而后者中的替换是表达式本身。因此 - 正如您在评论中所述 - 您需要调用Pattern.compile(Pattern.quote(inputText).replaceAll("%", "\\\\E.*\\\\Q"));(引用字符串和表达式中的反斜杠)。

来自String#replaceAll(...)的文档:

  

请注意,替换字符串中的反斜杠可能会导致结果与将其视为文字替换字符串时的结果不同。