正则表达式在一个单词中找到一组正则表达式

时间:2017-10-19 21:39:14

标签: c# .net regex

我想知道如何生成一个正则表达式来检测单词中正则表达式的所有组合。例如:

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

只检索我&#34; MAKE&#34;但是我想把这个词里面的所有比赛分组。

3 个答案:

答案 0 :(得分:1)

所以我试图用Regex对String子串生成器进行处理。 我有这个想法,但对我来说不是很清楚,但我终于得到了一个方法。没有对它进行过如此多的测试,但是现在它可以工作并为可变大小的未知单词创建所有可能的子串(从左到右)。

适用于C#Regex Engine。没有做基准测试也没有计算复杂度(看起来像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 );

应该在字典中的数组中找到所有四个单词。

答案 1 :(得分: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)

答案 2 :(得分:0)

如果您只需要一个正则表达式来匹配“MAKE”的所有连续子串,您可以使用以下内容:

M(|A(|K(|E)))|A(|K(|E)|K(|E)|E

或者,如果您不关心字符串匹配的开始和结束,可以将其缩短为:

What does Page() actually do?