Johannes Schaub - litb Johannes Schaub - litb - 1 month ago 13
Java Question

Wildcard matching in Java

I'm writing a simple debugging program that takes as input simple strings that can contain stars to indicate a wildcard match-any

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


I thought I would simply take that pattern, escape any regular expression special characters in it, then replace any
\\*
back to
.*
. And then use a regular expression matcher.

But I can't find any Java function to escape a regular expression. The best match I could find is
Pattern.quote
, which however just puts
\Q
and
\E
at the begin and end of the string.

Is there anything in Java that allows you to simply do that wildcard matching without you having to implement the algorithm from scratch?

Answer

Using A Simple Regex

One of this method's benefits is that we can easily add tokens besides * (see Adding Tokens at the bottom).

Search: [^*]+|(\*)

  • The left side of the | matches any chars that are not a star
  • The right side captures all stars to Group 1
  • If Group 1 is empty: replace with \Q + Match + E
  • If Group 1 is set: replace with .*

Here is some working code (see the output of the online demo).

Input: audio*2012*.wav

Output: \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);

Adding Tokens

Suppose we also want to convert the wildcard ?, which stands for a single character, by a dot. We just add a capture group to the regex, and exclude it from the matchall on the left:

Search: [^*?]+|(\*)|(\?)

In the replace function we the add something like:

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