Каждая ссылка на SQL, которую я могу найти, говорит, что подстановочный знак «любой отдельный символ» - это подчеркивание (_
), а не знак вопроса (?
). Это немного упрощает ситуацию, поскольку подчеркивание не является метасимволом регулярных выражений. Тем не менее, вы все равно не можете использовать Pattern.quote()
по причине, указанной mmyers. У меня есть другой метод для избежания регулярных выражений, когда я могу захотеть отредактировать их позже. После этого метод like()
становится довольно простым:
public static boolean like(final String str, final String expr)
{
String regex = quotemeta(expr);
regex = regex.replace("_", ".").replace("%", ".*?");
Pattern p = Pattern.compile(regex,
Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
return p.matcher(str).matches();
}
public static String quotemeta(String s)
{
if (s == null)
{
throw new IllegalArgumentException("String cannot be null");
}
int len = s.length();
if (len == 0)
{
return "";
}
StringBuilder sb = new StringBuilder(len * 2);
for (int i = 0; i < len; i++)
{
char c = s.charAt(i);
if ("[](){}.*+?$^|#\\".indexOf(c) != -1)
{
sb.append("\\");
}
sb.append(c);
}
return sb.toString();
}
Если вы действительно хотите использовать ?
для подстановочного знака, вам лучше всего удалить его из списка метасимволов в методе quotemeta()
. Замена его экранированной формы - replace("\\?", ".")
- не будет безопасной, поскольку в исходном выражении могут быть обратные слэши.
И это подводит нас к реальным проблемам: большинство разновидностей SQL, похоже, поддерживают классы символов в формах [a-z]
и [^j-m]
или [!j-m]
, и все они обеспечивают способ экранирования подстановочных символов. Последнее обычно делается с помощью ключевого слова ESCAPE
, которое позволяет вам каждый раз определять другой escape-символ. Как вы можете себе представить, это немного усложняет ситуацию. Преобразование в регулярное выражение, вероятно, все еще является лучшим вариантом, но анализ исходного выражения будет намного сложнее - фактически, первое, что вам нужно сделать, это формализовать синтаксис самих LIKE
-подобных выражений.