2013-01-18 34 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

相關問題