in java/tsfile/src/main/java/org/apache/tsfile/common/regexp/LikeMatcher.java [186:260]
static List<Pattern> parse(String pattern, Optional<Character> escape) {
List<Pattern> result = new ArrayList<>();
StringBuilder literal = new StringBuilder();
int anyCount = 0;
boolean anyUnbounded = false;
boolean inEscape = false;
for (int i = 0; i < pattern.length(); i++) {
char character = pattern.charAt(i);
if (inEscape) {
if (character != '%' && character != '_' && character != escape.get()) {
throw new IllegalArgumentException(
"Escape character must be followed by '%', '_' or the escape character itself");
}
literal.append(character);
inEscape = false;
} else if (escape.isPresent() && character == escape.get()) {
inEscape = true;
if (anyCount != 0) {
result.add(new Any(anyCount));
anyCount = 0;
}
if (anyUnbounded) {
result.add(new ZeroOrMore());
anyUnbounded = false;
}
} else if (character == '%' || character == '_') {
if (literal.length() != 0) {
result.add(new Literal(literal.toString()));
literal.setLength(0);
}
if (character == '%') {
anyUnbounded = true;
} else {
anyCount++;
}
} else {
if (anyCount != 0) {
result.add(new Any(anyCount));
anyCount = 0;
}
if (anyUnbounded) {
result.add(new ZeroOrMore());
anyUnbounded = false;
}
literal.append(character);
}
}
if (inEscape) {
throw new IllegalArgumentException(
"Escape character must be followed by '%', '_' or the escape character itself");
}
if (literal.length() != 0) {
result.add(new Literal(literal.toString()));
} else {
if (anyCount != 0) {
result.add(new Any(anyCount));
}
if (anyUnbounded) {
result.add(new ZeroOrMore());
}
}
return result;
}