Java中的通配符匹配


问题内容

我正在编写一个简单的调试程序,该程序将简单的字符串作为输入,其中可以包含星号以指示通配符匹配-任何

*.wav  // matches <anything>.wav
(*, a) // matches (<anything>, a)

我以为我会简单地采用该模式,转义其中的任何正则表达式特殊字符,然后将其替换\\*.*。然后使用正则表达式匹配器。

但是我找不到任何Java函数来转义正则表达式。我能找到的最佳匹配Pattern.quote,然而这正好将\Q\E在开始和字符串的结尾。

Java中有什么可以让您简单地进行通配符匹配而不必从头开始实现算法的?


问题答案:

使用一个简单的正则表达式

这种方法的好处之一是,我们还可以轻松添加令牌*(请参阅底部的 添加令牌 )。

搜索: [^*]+|(\*)

  • |匹配项的左侧匹配不是星号的所有字符
  • 右侧将所有星星捕获到第1组
  • 如果第1组为空:替换为\Q+匹配+E
  • 如果设置了组1:替换为 .*

这是一些工作代码(请参阅在线演示的输出)。

输入: audio*2012*.wav

输出: \Qaudio\E.*\Q2012\E.*\Q.wav\E

String subject = "audio*2012*.wav";
Pattern regex = Pattern.compile("[^*]+|(\\*)");
Matcher m = regex.matcher(subject);
StringBuffer b= new StringBuffer();
while (m.find()) {
    if(m.group(1) != null) m.appendReplacement(b, ".*");
    else m.appendReplacement(b, "\\\\Q" + m.group(0) + "\\\\E");
}
m.appendTail(b);
String replaced = b.toString();
System.out.println(replaced);

添加令牌

假设我们还想?用一个点将通配符(代表单个字符)转换。我们只是将捕获组添加到正则表达式,并将其从左侧的matchall中排除:

搜索: [^*?]+|(\*)|(\?)

在replace函数中,我们添加如下内容:

else if(m.group(2) != null) m.appendReplacement(b, ".");