java contains 通配符_如何在java中实现像'LIKE'运算符的SQL? Dovov编程网

。*将匹配正则expression式中的任何字符

我认为Java语法将是

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

而对于单个字符匹配只需使用一个点。

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

并匹配一个实际的点,逃避它作为斜线点

\.

是的,这可以用正则expression式来完成。 请记住,Java的正则expression式与SQL的“like”有不同的语法。 你可以用“ .* ”代替“ ? ”,而不用“ ? ”。

有些棘手的是,你也必须逃避Java认为特殊的字符。 既然你试图做类似于SQL,我猜猜^$[]{}\不应该出现在正则expression式string。 但是,在做任何其他replace之前,您必须将“ . ”replace为“ \\. ”。 ( 编辑: Pattern.quote(String)通过围绕string“ \Q ”和“ \E ”来转义所有东西,这将导致expression式中的所有内容都被当作文字(根本不使用通配符)。不想使用它。)

此外,正如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); }

正则expression式是最通用的。 但是,一些LIKE函数可以在没有正则expression式的情况下形成。 例如

String text = "digital"; text.startsWith("dig"); // like "dig%" text.endsWith("tal"); // like "%tal" text.contains("gita"); // like "%gita%"

我可以find的每个SQL引用都说“任何单个字符”通配符是下划线( _ ),而不是问号( ? )。 这简化了一些事情,因为下划线不是正则expression式元字符。 但是,你仍然不能使用Pattern.quote() ,因为mmyers给出的原因。 我在这里有另一种方法来逃避正则expression式,当我可能要编辑它们之后。 用这个方法, 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其转义forms – replace("\\?", ".") – 将是不安全的,因为原始expression式中可能有反斜杠。

这就给我们带来了真正的问题:大多数SQL风格似乎都支持forms为[az]和[^jm]或[!jm]字符类,它们都提供了一种转义通配符的方法。 后者通常是通过一个ESCAPE关键字来完成的,它可以让你每次定义一个不同的转义字符。 正如你所想象的,这使事情变得相当复杂。 转换为正则expression式可能仍然是最好的select,但parsing原始expression式会更困难 – 事实上,首先要做的就是forms化类LIKEexpression式本身的语法。

Javastring有.startsWith()和.contains()方法,这些方法可以帮你实现。 对于任何更复杂的事情,你必须使用正则expression式或编写自己的方法。

您可以将'%string%' contains() , 'string%' '%string"'作为endsWith() startsWith()和'%string"' 。

您也应该在string和模式上运行toLowerCase() ,因为LIKE不区分大小写。

不知道如何处理'%string%other%'除了正则expression式。

如果您使用正则expression式:

在replace%字符之前引用该string

注意LIKEstring中的转义字符

Apache Cayanne ORM有一个“ 内存评估 ”

它可能不适用于未映射的对象,但看起来很有希望:

Expression exp = ExpressionFactory.likeExp("artistName", "A%"); List startWithA = exp.filterObjects(artists);

要在java中实现sql的LIKE函数,你不需要正则expression式,它们可以被获得为:

String text = "apple"; text.startsWith("app"); // like "app%" text.endsWith("le"); // like "%le" text.contains("ppl"); // like "%ppl%"

我不知道这个贪婪的问题,但是如果它适合你,请试试这个:

public boolean like(final String str, String expr) { final String[] parts = expr.split("%"); final boolean traillingOp = expr.endsWith("%"); expr = ""; for (int i = 0, l = parts.length; i < l; ++i) { final String[] p = parts[i].split("\\\\\\?"); if (p.length > 1) { for (int y = 0, l2 = p.length; y < l2; ++y) { expr += p[y]; if (i + 1 < l2) expr += "."; } } else { expr += parts[i]; } if (i + 1 < l) expr += "%"; } if (traillingOp) expr += "%"; expr = expr.replace("?", "."); expr = expr.replace("%", ".*"); return str.matches(expr); }

Comparator和Comparable接口在这里可能不适用。 他们处理sorting,并返回任何符号或0的整数。您的操作是关于find匹配,并返回true / false。 那不一样。

public static boolean like(String toBeCompare, String by){ if(by != null){ if(toBeCompare != null){ if(by.startsWith("%") && by.endsWith("%")){ int index = toBeCompare.toLowerCase().indexOf(by.replace("%", "").toLowerCase()); if(index < 0){ return false; } else { return true; } } else if(by.startsWith("%")){ return toBeCompare.endsWith(by.replace("%", "")); } else if(by.endsWith("%")){ return toBeCompare.startsWith(by.replace("%", "")); } else { return toBeCompare.equals(by.replace("%", "")); } } else { return false; } } else { return false; } }

可能会帮助你

我在下面的代码中使用Java 8解决了这个问题

public List search(String value) { return listaPersonal.stream() .filter(p->(p.toUpperCase()).startsWith(value.toUpperCase())) .collect(Collectors.toList()); }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值