Java中的通配符匹配

新手上路,请多包涵

我正在编写一个简单的调试程序,它将简单的字符串作为输入,这些字符串可以包含星号以指示通配符匹配

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

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

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

Java 中是否有任何东西可以让您简单地进行通配符匹配,而无需从头开始实现算法?

原文由 Johannes Schaub - litb 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 905
2 个回答

使用简单的正则表达式

这种方法的好处之一是我们可以轻松地添加除了 * 之外的标记(请参阅底部的 添加标记)。

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

  • | 的左侧匹配任何不是星号的字符
  • 右侧将所有星星捕获到第 1 组
  • 如果第 1 组为空:替换为 \Q + Match + 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 中排除:

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

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

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

原文由 zx81 发布,翻译遵循 CC BY-SA 3.0 许可协议

Apache Commons-IO 库中有一个小的实用方法:org.apache.commons.io.FilenameUtils#wildcardMatch(),您可以在没有正则表达式复杂性的情况下使用它。

API 文档可在以下位置找到: https ://commons.apache.org/proper/commons-io/javadocs/api-2.5/org/apache/commons/io/FilenameUtils.html#wildcardMatch(java.lang.String,% 20java.lang.String)

原文由 Marek Gregor 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题