Raja Asthana
Raja Asthana

Reputation: 2100

Regex - Match Pattern with list of values

I have a input like google.com and a list of values like

 1. *.com
 2. *go*.com
 3. *abc.com
 4. *le.com
 5. *.*

I need to write a pattern in java which should return all the matches except *abc.com. I have tried a few but nothing worked as expected. Kindly help. Thanks in advance.

Update:

public static void main(String[] args) {
        List<String> values = new ArrayList<String>();
        values.add("*.com");
        values.add("*go*.com");
        values.add("*abc.com");
        values.add("*le.com");
        values.add("*.*");
        String stringToMatch = "google.com";
        for (String pattern : values) {
            String regex = Pattern.quote(pattern).replace("*", ".*");
            System.out.println(stringToMatch.matches(regex));
        }
    }

Output:

false
false
false
false
false

I have tried this but the pattern doesn't match.

Upvotes: 1

Views: 2837

Answers (4)

Sujith PS
Sujith PS

Reputation: 4864

You can use :

            List<String> values = new ArrayList<String>();
            values.add("*.com");
            values.add("*go*.com");
            values.add("*abc.com");
            values.add("*le.com");
            values.add("*.*");
            String stringToMatch = "google.com";
            for (String pattern : values) {
                String regex = pattern.replaceAll("[.]", "\\.").replaceAll("[*]", "\\.\\*");
                System.out.println(stringToMatch.matches(regex));
            }

Upvotes: 0

Bohemian
Bohemian

Reputation: 424983

Change this line in your code:

String regex = Pattern.quote(pattern).replace("*", ".*");

To this:

String regex = pattern.replace(".", "\\.").replace("*", ".*");

Upvotes: 1

sp00m
sp00m

Reputation: 48807

Based on a previous answer of mine (read the comments of the question, very instructive), here is a wildcardsToRegex method:

public static String wildcardsToRegex(String wildcards) {

    String regex = wildcards;

    // .matches() auto-anchors, so add [*] (i.e. "containing")
    regex = "*" + regex + "*";
    // replace any pair of backslashes by [*]
    regex = regex.replaceAll("(?<!\\\\)(\\\\\\\\)+(?!\\\\)", "*");
    // minimize unescaped redundant wildcards
    regex = regex.replaceAll("(?<!\\\\)[?]*[*][*?]+", "*");
    // escape unescaped regexps special chars, but [\], [?] and [*]
    regex = regex.replaceAll("(?<!\\\\)([|\\[\\]{}(),.^$+-])", "\\\\$1");
    // replace unescaped [?] by [.]
    regex = regex.replaceAll("(?<!\\\\)[?]", ".");
    // replace unescaped [*] by [.*]
    regex = regex.replaceAll("(?<!\\\\)[*]", ".*");
    // return whether data matches regex or not

    return regex;

}

Then, within your loop, use:

for (String pattern : values) {
    System.out.println(stringToMatch.matches(wildcardsToRegex(pattern)));
}

Upvotes: 2

Njol
Njol

Reputation: 3279

You could transform the given patterns into regexes, and then use normal regex functions like String.matches():

for (String pattern : patterns) {
    final String regex = pattern.replaceAll("[\\.\\[\\](){}?+|\\\\]", "\\\\$0").replace("*", ".*");
    System.out.println(stringToMatch.matches(regex));
}

edit: Apparently Pattern.quote() just adds \Q...\E around the string. Edited to use manual quoting.

edit 2: Another possibility is:

final String regex = Pattern.quote(pattern).replace("*", "\\E.*\\Q");

Upvotes: 2

Related Questions