如何匹配3个参数,包括通配符匹配?

我想定义一个由值组成的黑名单过滤器。让他们按照这个顺序。a, b, c


为了快速查找,我想将它们连接成一个,这样我就可以快速查找。这通常工作正常。Set<String>blacklist.contains(a+b+c)


问题:黑名单定义中的 3 个参数中除一个参数外的任何一个都可能被 wildcarted。因此,黑名单可能包含:*


OneTwoThree

*bc

因此,该方法调用 。旁注:方法输入参数当然可能不是通配符,而只是普通的字符串词。isBlacklisted("One", "b", "c") = true


问题是:我怎样才能更好地编写查找,如下所示?


private Set<String> blacklist; //concatenation of 3 fields 'a+b+c'


private boolean isBlacklisted(String a, String b, String c) {

    return blacklist.contains(a+b+c)

        || blacklist.contains("*"+b+c)

        || blacklist.contains(a+"*"+c)

        || blacklist.contains(a+b+"*")

        || blacklist.contains("**"+c)

        || blacklist.contains(a+"**")

        || blacklist.contains("*"+b+"*");

}

如何创建支持通配符的快速筛选器,而不必像我一样检查所有可能的串联通配符?


慕后森
浏览 135回答 3
3回答

慕桂英546537

当你写*时,你的意思是像“任何字符串”?如果是 - 只需使用正则表达式:for (String blacklist : blackRegex){&nbsp; &nbsp; Pattern p = Pattern.compile(blackRegex);&nbsp; &nbsp; Matcher matcher = p.matcher(string);&nbsp; &nbsp; if (matcher.find()&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;return true;&nbsp; &nbsp; }}return false;blackRegex的一个例子是(someA)(someB).*使用.*而不是*对于任何字符串,你可以按照java正则表达式指南。

当年话下

定义一个黑名单规则类:class BlackListRule {&nbsp; &nbsp; private String a;&nbsp; &nbsp; private String b;&nbsp; &nbsp; private String c;&nbsp; &nbsp; BlackListRule(String a, String b, String c) {&nbsp; &nbsp; &nbsp; &nbsp; this.a = a; this.b = b; this.c = c;&nbsp; &nbsp; }&nbsp; &nbsp; public boolean matches(String a, String b, String c) {&nbsp; &nbsp; &nbsp; &nbsp; return ("*".equals(this.a) || this.a.equals(a))&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&&("*".equals(this.b) || this.b.equals(b))&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&&("*".equals(this.c) || this.c.equals(c));&nbsp; &nbsp; }&nbsp; &nbsp; public int hashCode() {&nbsp; &nbsp; &nbsp; &nbsp; return Arrays.deepHashCode(new char[][]{a.toCharArray(), b.toCharArray(), c.toCharArray()});&nbsp; &nbsp; }&nbsp; &nbsp; public boolean equals(Object o) {&nbsp; &nbsp; &nbsp; &nbsp; return o instanceof BlackListRule && ((BlackListRule)o).hashCode() == hashCode();&nbsp; &nbsp; }}private Set<BlackListRule> blacklist;private boolean isBlacklisted(String a, String b, String c) {&nbsp; &nbsp; return blacklist.stream().anyMatch(rule -> rule.matches(a,b,c));}这是一个最小的工作示例,你绝对应该改进它,但你明白了。你可以在这里试试。

繁华开满天机

多亏了您的所有建议,我总结如下(假设黑名单定义来自db):对于每个“abc”黑名单元组,我创建了一个正则表达式模式。然后将这些模式与 OR 连接。|private void init(SqlRowSet set) {&nbsp; &nbsp; &nbsp; &nbsp; Set<String> patterns = new HashSet<>();&nbsp; &nbsp; &nbsp; &nbsp; while (set.next()) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; String a = set.getString(1);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; String b = set.getString(2);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; String c = set.getString(3);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; patterns.add(a + "/" + b + "/" + c);&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; regex = Pattern.compile(String.join("|", patterns));}private boolean isBlacklisted(String a, String b, String c) {&nbsp; &nbsp; return regex.matcher(a+"/"+b+"/"+c).matches();}现在,我可以创建我的黑名单,并将其与之匹配。a, b, .*isBlacklisted("a", "b", "anything") = true
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java