如何使用一个字符串来匹配许多规则?

时间:2013-01-18 10:29:31

标签: java regex

条件:

  1. 有许多规则,也许是数百个,如: {aab*, aabc*, aabcdd*, dtctddds*, *ddt*, *cddt*, *bcddt*, *t, *ttt, *ccddttt}

  2. 每次我得到一个字符串,那么我应该找到最长的匹配规则。

  3. 示例:

    示例1.string为aabcddttt匹配的规则应为:aabcdd*

    示例2.字符串accddttt匹配的规则应为*ccddttt

    问题: 我不想在长数组中使用规则来逐个匹配字符串,这是低效的方法。可能我应该使用字符串作为正则表达式来匹配百条规则。但我找不到优雅解决这个问题的方法。

    1. 我可以使用一些正则表达式来获得结果吗?
    2. 哪种是最好/最快的匹配方式?
    3. 首选Java,普通C或shell,请不要使用C ++ STL

2 个答案:

答案 0 :(得分:1)

Longest common substring

也许这个算法正是你要找的=)。


为什么不这样做?

String[] rules = {"^aab", "bcd", "aabcdd$", "dtctddds$", "^ddt$", "^cddt$", "^bcddt$", "^t", "^ttt", "^ccddttt"};
        String testCase = "aabcddttt";

        for (int i = 0; i < rules.length; i++) {
            Pattern p = Pattern.compile(rules[i]);
            Matcher m = p.matcher(testCase);
            if (m.find()) {
                System.out.println("String: " + testCase + " has matched the pattern " + rules[i]);
            }
        }

所以基本上在这种情况下,规则[0],因为胡萝卜(^)意味着字符串必须以^ aab开头。另一方面,bba $表示字符串必须以bba结尾。找到规则1是因为它意味着规则可以出现在testCase的任何地方(例如bcd)。

答案 1 :(得分:0)

您可以尝试使用每个子规则周围的括号将它们全部匹配。您可以使用该组来确定哪个匹配。

public static void main(String... ignored) {
    for (String test : "aabaa,wwwaabcdddd,abcddtxyz".split(",")) {
        System.out.println(test + " matches " + longestMatch(test, "aab*", "aabc*", "aabcdd*", "dtctddds*", "ddt"));
    }
}

public static String longestMatch(String text, String... regex) {
    String[] sortedRegex = regex.clone();
    Arrays.sort(sortedRegex, new Comparator<String>() {
        @Override
        public int compare(String o1, String o2) {
            return o2.length() - o1.length();
        }
    });
    StringBuilder sb = new StringBuilder();
    String sep = "(";
    for (String s : sortedRegex) {
        sb.append(sep).append('(').append(s).append(')');
        sep = "|";
    }
    sb.append(")");
    Matcher matcher = Pattern.compile(sb.toString()).matcher(text);
    if (matcher.find()) {
        for (int i = 2; i <= matcher.groupCount(); i++) {
            String group = matcher.group(i);
            if (group != null)
                return sortedRegex[i - 2];
        }
    }
    return "";
}

打印

aabaa matches aabc*
wwwaabcdddd matches aabcdd*
abcddtxyz matches ddt