Skip to content

Instantly share code, notes, and snippets.

@ogregoire
Created December 29, 2015 17:25
Show Gist options
  • Save ogregoire/017c2e007f743949234c to your computer and use it in GitHub Desktop.
Save ogregoire/017c2e007f743949234c to your computer and use it in GitHub Desktop.
Glob Java
import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;
public class Glob {
public static Glob compile(String pattern) {
return new Glob(Pattern.compile(globToRegex(pattern)));
}
private final Pattern pattern;
private Glob(Pattern pattern) {
this.pattern = pattern;
}
public boolean matches(CharSequence input) {
return pattern.matcher(input).matches();
}
private static final String REGEX_META = ".^$+{[]|()";
private static final String GLOB_META = "\\*?{";
static String globToRegex(final String glob) {
CharIterator chars = new CharIterator(glob);
boolean inGroup = false;
StringBuilder regex = new StringBuilder("^");
while (chars.hasNext()) {
char c = chars.next();
switch (c) {
case '\\':
if (!chars.hasNext()) {
throw new PatternSyntaxException("No character to escape", glob, chars.index - 1);
}
char next = chars.next();
if (GLOB_META.indexOf(next) >= 0 || REGEX_META.indexOf(next) >= 0) {
regex.append('\\');
}
regex.append(next);
break;
case '/':
regex.append('/');
break;
case '{':
if (inGroup) {
throw new PatternSyntaxException("Cannot nest groups", glob, chars.index - 1);
}
regex.append("(?:(?:");
inGroup = true;
break;
case '}':
if (inGroup) {
regex.append("))");
inGroup = false;
} else {
regex.append('}');
}
break;
case ',':
if (inGroup) {
regex.append(")|(?:");
} else {
regex.append(',');
}
break;
case '*':
if (chars.peekNext() == '*') {
regex.append(".*");
chars.next();
} else {
regex.append("[^/]*");
}
break;
case '?':
regex.append("[^/]");
break;
default:
if (REGEX_META.indexOf(c) >= 0) {
regex.append('\\');
}
regex.append(c);
}
}
if (inGroup) {
throw new PatternSyntaxException("Missing '}", glob, chars.index - 1);
}
return regex.append('$').toString();
}
private static class CharIterator {
char[] chars;
int index = 0;
CharIterator(String s) {
chars = s.toCharArray();
}
boolean hasNext() {
return index < chars.length;
}
char next() {
return chars[index++];
}
char peekNext() {
return index + 1 < chars.length ? chars[index] : (char) 0xFFFF;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment