5

这就是问题所在:向用户呈现一个文本字段,他或她可以在该字段上键入过滤器。过滤器,用于过滤未过滤的数据。经历 Oracle Forms 洗脑的用户,除了 % 之外没有其他特殊字符,我猜它或多或少代表 Java 中的“.*”正则表达式。

如果用户行为良好,给定的人会输入“CTHULH%”之类的东西,在这种情况下,我可以构建一个模式:

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

但是,如果用户来自印斯茅斯,他将无法通过几个简单的按键输入“.+\[a-#$%^&*(”来破坏我的方案。这将不起作用:

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

因为它会将 \Q 放在字符串的开头,将 \E 放在字符串的末尾,从而使我的 % -> .* 开关没有意义。

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

4

2 回答 2

6

我认为这个算法应该适合你:

  • 拆分开%
  • 使用单独引用每个部分Pattern.quote
  • 加入字符串使用.*
于 2012-05-09T15:06:40.363 回答
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(...)我忘记了and之间的区别replaceAll(...):前者中的替换参数是文字,而后者中的替换参数是表达式本身。因此 - 正如您在评论中已经说明的那样 - 您需要调用Pattern.compile(Pattern.quote(inputText).replaceAll("%", "\\\\E.*\\\\Q"));(引用字符串和表达式中的反斜杠)。

从文档中String#replaceAll(...)

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

于 2012-05-09T15:11:19.600 回答