繁体   English   中英

如何匹配包括通配符匹配在内的3个参数?

[英]How to match 3 parameters including wildcard matches?

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

为了快速查找,我考虑将它们连接成一个Set<String> ,这样我就可以快速查找blacklist.contains(a+b+c) 这一般工作得很好。

问题: 黑名单定义中的3个参数中的任何一个都可以是通配符* 所以黑名单可能包含:

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+"*");
}

如何创建支持通配符的快速过滤器,而不必像我那样检查所有可能的连接通配符?

当你写*你的意思是“任何字符串”?
如果是 - 只需使用正则表达式

for (String blacklist : blackRegex)
{
    Pattern p = Pattern.compile(blackRegex);
    Matcher matcher = p.matcher(string);
    if (matcher.find()
    {
           return true;
    }
}

return false;

blackRegex的一个例子是(someA)(someB)。*
对任何字符串使用。*而不是* ,你可以遵循java正则表达式指南

定义BlackListRule类:

class BlackListRule {
    private String a;
    private String b;
    private String c;

    BlackListRule(String a, String b, String c) {
        this.a = a; this.b = b; this.c = c;
    }

    public boolean matches(String a, String b, String c) {
        return ("*".equals(this.a) || this.a.equals(a))
             &&("*".equals(this.b) || this.b.equals(b))
             &&("*".equals(this.c) || this.c.equals(c));
    }

    public int hashCode() {
        return Arrays.deepHashCode(new char[][]{a.toCharArray(), b.toCharArray(), c.toCharArray()});
    }

    public boolean equals(Object o) {
        return o instanceof BlackListRule && ((BlackListRule)o).hashCode() == hashCode();
    }
}
private Set<BlackListRule> blacklist;
private boolean isBlacklisted(String a, String b, String c) {
    return blacklist.stream().anyMatch(rule -> rule.matches(a,b,c));
}

这是一个最小的工作示例,你绝对应该改进它,但你明白了。

你可以在这里试试

感谢你的所有建议,我结束如下(假设黑名单定义来自db):对于每个“abc”黑名单元组,我创建一个正则表达式模式。 然后将这些模式与OR |连接

private void init(SqlRowSet set) {
        Set<String> patterns = new HashSet<>();
        while (set.next()) {
            String a = set.getString(1);
            String b = set.getString(2);
            String c = set.getString(3);

            patterns.add(a + "/" + b + "/" + c);
        }

        regex = Pattern.compile(String.join("|", patterns));
}

private boolean isBlacklisted(String a, String b, String c) {
    return regex.matcher(a+"/"+b+"/"+c).matches();
}

现在我可以使用a, b, .*创建我的黑名单,并将其与isBlacklisted("a", "b", "anything") = true匹配。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM