Каждый 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
.
Да, спасибо! Но в случае, если слово не так просто, как «% dig%», а строка требует некоторого escping? Есть ли что-то уже выходящее? Что насчет '?' ? – Chris
Я отредактировал свой ответ для оператора вопросительного знака. Я немного смущен остальными вашими комментариями. Вы говорите, что строка подходит вам в синтаксисе sql, и вы хотите оценить ее как есть? Если это так, я думаю, вам нужно будет заменить синтаксис sql вручную. – Bob
Что делать, если строка, которая используется в качестве шаблона поиска, содержит группировку символов, таких как '(' или ')', чтобы избежать их? как mayn другие персонажи должны убегать? – Chris