如何在java中实现类似“LIKE”运算符的SQL?

2022-09-01 00:19:39

我需要一个java中的比较器,它与sql 'like'运算符具有相同的语义。例如:

myComparator.like("digital","%ital%");
myComparator.like("digital","%gi?a%");
myComparator.like("digital","digi%");

应计算为 true,并且

myComparator.like("digital","%cam%");
myComparator.like("digital","tal%");

应计算为假。如何实现这样的比较器的任何想法,或者有人知道具有相同语义的实现吗?这可以使用正则表达式来完成吗?


答案 1

.* 将匹配正则表达式中的任何字符

我认为java语法将是

"digital".matches(".*ital.*");

对于单个字符匹配,只需使用单个点即可。

"digital".matches(".*gi.a.*");

为了匹配实际的点,请将其转义为斜杠点

\.

答案 2

是的,这可以通过正则表达式来完成。请记住,Java的正则表达式与SQL的“like”具有不同的语法。而不是“”,你会有“”,而不是“”,你会有“”。%.*?.

让它有点棘手的是,你还必须转义Java视为特殊字符的任何字符。由于您试图将其与SQL相似,因此我猜这不应该出现在正则表达式字符串中。但是,在执行任何其他替换之前,您必须将“”替换为“”。(编辑:Pattern.quote(String)通过用“”和“”将字符串括起来来转义所有内容,这将导致表达式中的所有内容都被视为文本(根本没有通配符)。所以你绝对不想使用它。^$[]{}\.\\.\Q\E

此外,正如戴夫·韦伯(Dave Webb)所说,你还需要忽略案例。

考虑到这一点,以下是它可能看起来像什么的示例:

public static boolean like(String str, String expr) {
    expr = expr.toLowerCase(); // ignoring locale for now
    expr = expr.replace(".", "\\."); // "\\" is escaped to "\" (thanks, Alan M)
    // ... escape any other potentially problematic characters here
    expr = expr.replace("?", ".");
    expr = expr.replace("%", ".*");
    str = str.toLowerCase();
    return str.matches(expr);
}