私が見つけることができるすべてのSQL参照は、「任意の1文字」ワイルドカードが_疑問符()ではなくアンダースコア()であると述べてい?ます。アンダースコアは正規表現のメタ文字ではないため、これにより少し単純化されます。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キーワードを使用して実行されます。これにより、毎回異なるエスケープ文字を定義できます。ご想像のとおり、これは物事をかなり複雑にします。正規表現への変換はおそらく依然として最良のオプションですが、元の式の解析ははるかに困難になります。実際、最初に行う必要があるのは、LIKE-like式自体の構文を形式化することです。