2013-01-18 33 views
-1

条件:如何使用一个字符串匹配许多规则

  1. 有很多的规则,也许几百个,它们是这样的:
    {aab*, aabc*, aabcdd*, dtctddds*, *ddt*, *cddt*, *bcddt*, *t, *ttt, *ccddttt}

  2. 每次

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

实例:

例如1.string是aabcddttt匹配的规则应该是:aabcdd*

实施例2的字符串是accddttt匹配的规则应当是*ccddttt

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

  1. 我可以使用一些正则表达式来得到结果吗?
  2. 哪种配对最好/最快的方式?

Java中,普通C或外壳是首选,请不要使用C++ STL

+0

这是转让吗?你有什么尝试? – Swapnil

+0

不,这不是一项任务。这是我同事工作中的一项小任务。我尝试了一些方法,如下面的第一个答案,但我认为这不是最好的方法。 – user1989706

回答

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 
+0

比使用逐一匹配更好吗? –

+0

@NikitaBeloglazov这取决于'compile()'的智能程度。它可能能够简化搜索的重复,或者可能会更糟。你将不得不测试它才能看到。如果查询可以预先构建为一个,它可能会更好。 –

+2

@PeterLawrey:OP的“规则”对我来说看起来像是一个圈套。你需要通过用'替换'*来将它们翻译成正则表达式。*'并添加锚点。或者使用'matches()'方法而不是'find()',并且不用介意锚点。 –

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发现因为胡萝卜(^)指字符串必须以^ AAB开始。另一方面,bba $表示字符串必须以bba结尾。并且规则1被找到,因为它意味着规则可以出现在测试用例的任何地方(例如bcd)。

+0

哦,是的,抱歉 – Jason

相关问题