Java string matching with wildcards

13,655

Solution 1

Just use bash style pattern to Java style pattern converter:

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

Solution 2

you can use stringVariable.startsWith("abc")

Solution 3

abc* would be the RegEx that matches ab, abc, abcc, abccc and so on.
What you want is abc.* - if abc is supposed to be the beginning of the matched string and it's optional if anything follows it.
Otherwise you could prepend .* to also match strings with abc in the middle: .*abc.*

Generally i recommend playing around with a site like this to learn RegEx. You are asking for a pretty basic pattern but it's hard to say what you need exactly. Good Luck!

EDIT:
It seems like you want the user to type a part of a file name (or so) and you want to offer something like a search functionality (you could have made that clear in your question IMO). In this case you could bake your own RegEx from the users' input:

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

Of course that's just a very simple example. You could modify this and then use the RegEx to match file names.

Share:
13,655

Related videos on Youtube

Sunil Kumar B M
Author by

Sunil Kumar B M

A passionate Software Engineer with experience in Java and web technologies.

Updated on June 04, 2022

Comments

  • Sunil Kumar B M
    Sunil Kumar B M almost 2 years

    I have a pattern string with a wild card say X (E.g.: abc*).

    Also I have a set of strings which I have to match against the given pattern.

    E.g.:

    abf - false

    abc_fgh - true

    abcgafa - true

    fgabcafa - false

    I tried using regex for the same, it didn't work.

    Here is my code

    String pattern = "abc*";
    String str = "abcdef";
    
    Pattern regex = Pattern.compile(pattern);
    
    return regex.matcher(str).matches();
    

    This returns false

    Is there any other way to make this work?

    Thanks

    • anubhava
      anubhava almost 7 years
      Can you show your code. What are all the wild cards you want to support?
    • Ivar
      Ivar almost 7 years
      Why didn't the regex work? What did you try?
    • Scary Wombat
      Scary Wombat almost 7 years
      show us what you tried - maybe a simple fix
    • Avinash Raj
      Avinash Raj almost 7 years
      you mean abc.+ ?
    • Scary Wombat
      Scary Wombat almost 7 years
      why not just use String.contains ?
    • Thomas
      Thomas almost 7 years
      That should be easy to do with regex, just replace the wildcards with the appropriate expression (e.g. .* for * and . for ?) and use String#matches().
    • Thomas
      Thomas almost 7 years
      @ScaryWombat fgabcafa should not match but it would with "fgabcafa".contains("abc")
    • Sunflame
      Sunflame almost 7 years
      @Thomas that is not working but he can use the String::startsWith method. But the best is to use regexps.
    • Scary Wombat
      Scary Wombat almost 7 years
      @Thomas Oh sorry, I was reading the OP's question as that were his results, not what he was wanting - in that case startsWith
    • Thomas
      Thomas almost 7 years
      @Sunflame why shouldn't that be working if he's using the correct regex? Assuming the wildcards can be anywhere (and probably multiple wildcards as well) you can't just use startsWith(), contains() or endsWith().
  • Sunil Kumar B M
    Sunil Kumar B M almost 7 years
    Thanks.. but what I really want is linux style file matching like E.g: ls .sh will give all files ending with .sh or ls abc will give files starting with abc... I don't have control over the pattern or the actual strings...
  • bkis
    bkis almost 7 years
    Why don't you have control over the pattern? Does a user input the pattern?
  • Sunil Kumar B M
    Sunil Kumar B M almost 7 years
    yes.. user give the pattern input.. and strings are a list of file names which I have to match
  • bkis
    bkis almost 7 years
    [a][b][c].* doesn't make sense. You are creating character classes with only one character in them. It's the same as abc.*
  • Sunflame
    Sunflame almost 7 years
    Yes you are right, I was checking with the IntelliJ built in Regexp check, and Idk why it didn't work with abc.*.
  • Sunil Kumar B M
    Sunil Kumar B M almost 7 years
    that won't work... the input pattern provided is abc*, and basically, it could be anything like .sh, abc, I'm looking for linux style pattern matching
  • Thomas
    Thomas almost 7 years
    Note that String#matches() doesn't require the expression to be wrapped in ^...$ since that's done implicitly anyways.
  • Sunil Kumar B M
    Sunil Kumar B M almost 7 years
    @Thomas - noted.. pattern matching works without ^...$ wrapper also