package helper; /** * Glob-style string matching and substring extraction. Glob was implemented by * translating the glob package for tcl8.0. *
true
if the string matched the pattern,
* false
otherwise.
*/
public static boolean match(String pattern, String string) {
return Glob.match(pattern, string, null);
}
/**
* Match a string against a pattern, and return sub-matches.
*
* The caller can provide an array of strings that will be filled in with
* the substrings of string
that matched the glob
* meta-characters in pattern
. The array of strings may be
* partially modified even if the string did not match the glob pattern. The
* array may contain more elements than glob meta-characters, in which case
* those extra elements will not be modified; the array may also contain
* fewer elements or even be null
, to ignore some or all of
* the glob meta-characters. In other words, the user can pass pretty much
* anything and this method defines errors out of existence.
*
* @param pattern
* Glob pattern.
*
* @param string
* String to match against pattern.
*
* @param substr
* Array of strings provided by the caller, to be filled in with
* the substrings that matched the glob meta-characters. May be
* null
.
*
* @return true
if the string matched the pattern,
* false
otherwise.
*/
public static boolean match(String pattern, String string, String[] substr) {
return pattern != null && Glob.match(pattern, 0, string, 0, substr, 0);
}
private static boolean match(String pat, int pIndex, String str,
int sIndex, String[] substrs, int subIndex) {
final int pLen = pat.length();
final int sLen = str.length();
while (true) {
if (pIndex == pLen) {
if (sIndex == sLen) {
return true;
} else {
return false;
}
} else if (sIndex == sLen && pat.charAt(pIndex) != '*') {
return false;
}
switch (pat.charAt(pIndex)) {
case '*': {
final int start = sIndex;
pIndex++;
if (pIndex >= pLen) {
Glob.addMatch(str, start, sLen, substrs, subIndex);
return true;
}
while (true) {
if (Glob.match(pat, pIndex, str, sIndex, substrs,
subIndex + 1)) {
Glob.addMatch(str, start, sIndex, substrs, subIndex);
return true;
}
if (sIndex == sLen) {
return false;
}
sIndex++;
}
}
case '?': {
pIndex++;
Glob.addMatch(str, sIndex, sIndex + 1, substrs, subIndex++);
sIndex++;
break;
}
case '[': {
try {
pIndex++;
final char s = str.charAt(sIndex);
char p = pat.charAt(pIndex);
while (true) {
if (p == ']') {
return false;
}
if (p == s) {
break;
}
pIndex++;
char next = pat.charAt(pIndex);
if (next == '-') {
pIndex++;
final char p2 = pat.charAt(pIndex);
if (p <= s && s <= p2) {
break;
}
pIndex++;
next = pat.charAt(pIndex);
}
p = next;
}
pIndex = pat.indexOf(']', pIndex) + 1;
if (pIndex <= 0) {
return false;
}
Glob.addMatch(str, sIndex, sIndex + 1, substrs, subIndex++);
sIndex++;
} catch (final StringIndexOutOfBoundsException e) {
/*
* Easier just to catch malformed [] sequences than to check
* bounds all the time.
*/
return false;
}
break;
}
case '\\': {
pIndex++;
if (pIndex >= pLen) {
return false;
}
// fall through
}
default: {
if (pat.charAt(pIndex) != str.charAt(sIndex)) {
return false;
}
pIndex++;
sIndex++;
}
}
}
}
private static void addMatch(String str, int start, int end,
String[] substrs, int subIndex) {
if (substrs == null || subIndex >= substrs.length) {
return;
}
substrs[subIndex] = str.substring(start, end);
}
}