2017-10-19 27 views
2

內。例如:正則表達式找到正則表達式的組,我想知道如何生成檢測字裏面正則表達式的所有組合正則表達式一個字

比賽爲"MAKE"應該返回"M", "MA", "MAK", "MAKE", "AKE", "AK", "A", "KE, "K", "E"

因此,對於所有這些可能的值的正則表達式是[A-Za-z]+

的問題是,我該如何檢索一個字的所有可能值:

Regex regex = new Regex("[A-Za-z]+"); 
foreach(Match m in regex.Matches(word)) 
{ 
    for(int i = 0; i < m.Groups.Count; i++) 
     Console.WriteLine(m.Groups[i].Value); 
} 

只檢索我「作」,但我想這組字裏面的所有比賽。

+0

你不能讓正則表達式引擎在同一個地方多次匹配。這意味着你不能用一個正則表達式來解決這個問題。創建沒有正則表達式的字符串的所有可能的排列。 –

+0

@WiktorStribiżew所以我的猜測是手動創建方法來查找單詞內所有可能的子字符串。我只是想讓引擎爆炸(: –

+0

)對不起,但正則表達式並不意味着創建這樣的排列。你可以使用嵌套的捕獲組捕獲從同一點開始的值(比如(((((M)A)K)E)'),但我懷疑它是你需要的。 –

回答

1

所以我試圖讓正則表達式的String子字符串生成器的方法。 我有想法,但它不是很清楚,但我終於有了一個辦法。沒有太多的測試,但現在它工作並創建所有可能的子字符串(從左到右)爲一個可變大小的未知單詞。

它適用於C#正則表達式引擎。沒有完成基準測試,也沒有計算複雜性(看起來像O(N^2)?)。

我想對我在微軟採訪了幾個小時前給定問題的不同的方法。重點是在對角線,水平和垂直(從左到右和從上到下)的N個N個單詞的矩陣(在下面的例子中,4個單詞的大小爲4)內找到所有可能的單詞。

static void CheckWords(String[] words, HashSet<String> valid) 
    { 
     //Horizontal 
     foreach(var w in words) 
      FindWords(w, valid); 

     //Vertical 
     String word = ""; 
     for(int i = 0; i < words.Length; i++) 
     { 
      for(int j = 0; j < words[i].Length; j++) 
       word += words[j][i]; 

      FindWords(word, valid); 
      word = ""; 
     } 

     //Diagonal 
     String word2 = ""; 
     for(int i = 0, j = 0; i < words.Length; i++, j++) 
     { 
      word += words[i][j]; 
      word2 += words[i][words[i].Length - i - 1]; 
     } 

     FindWords(word, valid); 
     FindWords(word2, valid); 

    } 

    static void FindWords(String word, HashSet<string> valid) 
    { 
     int len = word.Length; 
     //Generate all possible (left to right) substring for String with Length - a [ FOr example, for "MAKE" we can have possible values for "MAKE", "MAK", "MA", "M", "AKE", "KE", "K, "E", "A 
     for(int a = 0; a < len; a++) 
     { 
      //Find all possible substring with this length { k = 1, k = 2, k = 3, ..., k = word.Length } 
      for(int k = 1; k <= word.Length; k++) 
      { 
       Match match = new Regex(@"([A-Za-z]{" + k + "}){1}").Match(word); 
       //For all found groups, we just care for the first group wich contains the main unrepeated substrings 
       for(int i = 0; i < match.Groups.Count - 1; i++) 
        for(int j = 0; j < match.Groups[i].Captures.Count; j++) //Check each permutation for each word with K length. You can Console.Write each value to check it's generated string 
         if(valid.Contains(match.Groups[i].Captures[j].Value)) 
          Console.WriteLine(match.Groups[i].Captures[j].Value); 
      } 
      word = word.Substring(1, word.Length - 1); 
     } 
    } 

因此,考慮此輸入:

HashSet<String> words = new HashSet<string>(); 
    words.Add("MAKE"); 
    words.Add("MAD");   
    words.Add("END"); 
    words.Add("MINE");     

    String[] array = { "MAKE", "IEMY", "NIAH", "ENDN" }; 

    CheckWords(array, words); 

應該找到在詞典中的陣列中的所有四個字。

0

你可以像下面這樣做

((((M)(?=(((A)K)E))A)(?=((K)E))K)(?=(E))E)

有使用給定詞來構造一個正則表達式的編程方式。
這是我手工製作這個正則表達式的方式。 我會把它作爲練習讓你部署它。

** Grp 0 - (pos 0 : len 4) 
MAKE 
** Grp 1 - (pos 0 : len 4) 
MAKE 
** Grp 2 - (pos 0 : len 3) 
MAK 
** Grp 3 - (pos 0 : len 2) 
MA 
** Grp 4 - (pos 0 : len 1) 
M 
** Grp 5 - (pos 1 : len 3) 
AKE 
** Grp 6 - (pos 1 : len 2) 
AK 
** Grp 7 - (pos 1 : len 1) 
A 
** Grp 8 - (pos 2 : len 2) 
KE 
** Grp 9 - (pos 2 : len 1) 
K 
** Grp 10 - (pos 3 : len 1) 
E 

格式化和血淋淋的細節:

(       # (1 start) 
     (       # (2 start) 
      (       # (3 start) 
       (M)       # (4) 
       (?= 
        (       # (5 start) 
          (       # (6 start) 
           (A)       # (7) 
           K 
         )        # (6 end) 
          E 
        )        # (5 end) 
       ) 
       A 
      )        # (3 end) 
      (?= 
       (       # (8 start) 
        (K)       # (9) 
        E 
       )        # (8 end) 
      ) 
      K 
    )        # (2 end) 
     (?= 
      (E)       # (10) 
    ) 
     E 
)        # (1 end) 
+0

謝謝!儘管我希望自動完成未知字符串的未知長度。我其實一直在做測試,我終於明白了:) –

+0

有人可以說爲什麼downvote? –

0

如果你只需要一個正則表達式匹配的 「MAKE」 所有連續子,你可以使用以下命令:

^(M(|A(|K(|E)))|A(|K(|E))|K(|E)|E)$ 

另外,如果你不關心的開始和字符串匹配的結束,你可以把它縮短到:

M(|A(|K(|E)))|A(|K(|E)|K(|E)|E 
+0

有人可以說爲什麼downvote? –