【问题标题】:Java string matching with wildcards与通配符匹配的 Java 字符串
【发布时间】:2018-01-01 10:16:03
【问题描述】:

我有一个带有通配符 X 的模式字符串(例如:abc*)。

我还有一组字符串,我必须匹配给定的模式。

例如:

abf - 错误

abc_fgh - 真

abcgafa - 真

fgabcafa - 错误

我尝试使用正则表达式,但没有成功。

这是我的代码

String pattern = "abc*";
String str = "abcdef";

Pattern regex = Pattern.compile(pattern);

return regex.matcher(str).matches();

这返回错误

有没有其他方法可以做到这一点?

谢谢

【问题讨论】:

  • 你能显示你的代码吗?您想支持哪些通配符?
  • 为什么正则表达式不起作用?你尝试了什么?
  • 向我们展示你的尝试——也许是一个简单的修复
  • 你的意思是abc.+
  • 为什么不直接使用String.contains

标签: java regex pattern-matching wildcard


【解决方案1】:

只需使用 bash 样式模式到 Java 样式模式转换器:

public static void main(String[] args) {
        String patternString = createRegexFromGlob("abc*");
        List<String> list = Arrays.asList("abf", "abc_fgh", "abcgafa", "fgabcafa");
        list.forEach(it -> System.out.println(it.matches(patternString)));
}

private static String createRegexFromGlob(String glob) {
    StringBuilder out = new StringBuilder("^");
    for(int i = 0; i < glob.length(); ++i) {
        final char c = glob.charAt(i);
        switch(c) {
            case '*': out.append(".*"); break;
            case '?': out.append('.'); break;
            case '.': out.append("\\."); break;
            case '\\': out.append("\\\\"); break;
            default: out.append(c);
        }
    }
    out.append('$');
    return out.toString();
}

Is there an equivalent of java.util.regex for “glob” type patterns?
Convert wildcard to a regex expression

【讨论】:

  • 请注意,String#matches() 不需要将表达式包装在 ^...$ 中,因为无论如何这都是隐式完成的。
  • @Thomas - 注意.. 模式匹配也可以在没有 ^...$ 包装器的情况下工作
【解决方案2】:

abc* 将是匹配 ababcabccabccc 等的正则表达式。
您想要的是 abc.* - 如果 abc 应该是匹配字符串的开头,并且如果后面有任何内容,则它是可选的。
否则,您可以在.* 前面加上中间带有abc 的字符串:.*abc.*

一般来说,我建议使用this 之类的网站来学习 RegEx。你要求一个非常基本的模式,但很难说你到底需要什么。祝你好运!

编辑:
似乎您希望用户输入文件名的一部分(或左右),并且您想提供类似搜索功能的功能(您可以在问题 IMO 中明确说明)。在这种情况下,您可以根据用户的输入烘焙自己的 RegEx:

private Pattern getSearchRegEx(String userInput){
    return Pattern.compile(".*" + userInput + ".*");
}

当然,这只是一个非常简单的例子。您可以修改它,然后使用 RegEx 匹配文件名。

【讨论】:

  • 谢谢.. 但我真正想要的是 linux 样式文件匹配,例如: ls .sh 将给出所有以 .sh 结尾的文件或 ls abc 将给出以开头的文件abc...我无法控制模式或实际字符串...
  • 你为什么不能控制模式?用户是否输入了模式?
  • 是.. 用户提供模式输入.. 字符串是我必须匹配的文件名列表
【解决方案3】:

你可以使用 stringVariable.startsWith("abc")

【讨论】:

  • 那行不通...提供的输入模式是abc*,基本上,它可以是.sh,abc之类的任何东西,我正在寻找linux样式模式匹配
【解决方案4】:

所以我认为这是你的答案: 您正在寻找的正则表达式是这样的:[a][b][c].*

这是我的有效代码:

    String first = "abc"; // true
    String second = "abctest"; // true
    String third = "sthabcsth"; // false

    Pattern pattern = Pattern.compile("[a][b][c].*");

    System.out.println(first.matches(pattern.pattern())); // true
    System.out.println(second.matches(pattern.pattern())); // true
    System.out.println(third.matches(pattern.pattern())); // false

但是如果你只想检查是否以开头或结尾,你可以使用String的方法:.startsWith()endsWith()

【讨论】:

  • [a][b][c].* 没有意义。您正在创建其中只有一个字符的字符类。同abc.*
  • 是的,你是对的,我正在检查 IntelliJ 内置的 Regexp 检查,以及为什么它不适用于 abc.*。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-09-04
  • 1970-01-01
  • 1970-01-01
  • 2010-10-22
相关资源
最近更新 更多