Регулярные выражения на C#

Рейтинг: -1Ответов: 1Опубликовано: 24.02.2023

У меня есть алфавит {a,b,c}. Для него нужно составить регулярное выражение по предложению "Произвольная цепочка символов a, b и c, заканчивающаяся символами сс".
По идее это (a|b|c)*(cc)
Но проверка через Regex.IsMatch выводит мне и слова, начинающиеся с cc

using System; 
using System.Text.RegularExpressions; 
 
class Program 
{ 
    static char[] alphabet = { 'a', 'b', 'c' }; 
    static List<string> GenerateWords(int n) 
    { 
        List<string> words = new(); 
        int alphabetSize = alphabet.Length; 
        int[] indices = new int[n]; 
 
        for (int i = 0; i < n; i++) 
        { 
            // Convert index to base-alphabet and append corresponding letters 
            string word = ""; 
            int index = i; 
            while (index > 0) 
            { 
                int remainder = index % alphabetSize; 
                word = alphabet[remainder] + word; 
                index /= alphabetSize; 
            } 
            while (word.Length < 1) 
            { 
                word = alphabet[0] + word; 
            } 
            Console.WriteLine(word); 
            words.Add(word); 
        } 
        return words; 
    } 
    static void FindRegex(List<string> words, string finalChars) 
    { 
        string regex = "("; 
        for (int i= 0;i<alphabet.Length;i++) 
        { 
            regex += alphabet[i]; 
            if (i != alphabet.Length - 1) regex += '|'; 
        } 
        regex += ")*(" + finalChars+')'; 
        Console.WriteLine("Regular expression: " + regex); 
 
        List<string> matchingWords = new List<string>(); 
        foreach (string word in words) 
        { 
            if (Regex.IsMatch(word, regex)) 
            { 
                matchingWords.Add(word); 
            } 
        } 
        if (matchingWords.Count == 0) Console.WriteLine("Words not found or final symbols are not contained in this alphabet"); 
        else 
        { 
            Console.WriteLine("Matching words: "); 
            foreach (string word in matchingWords) 
            { 
                Console.WriteLine(word); 
            } 
        } 
        
 
    } 
    static void Main(string[] args) 
    { 
        List<string> words= GenerateWords(30); 
        FindRegex(words, "cc");   
    }  
}

1

Ответы

▲ 1

В регулярном выражении не указано, что не может быть других символов.

Таким образом выбранные строки вполне подходят под выражение: пустая последовательность a|b|c после которой идет cc.

Для исправления достаточно указать $ который сопоставляется с концом строки, чтобы явно указать, что cc должны быть именно у конца строки.

Также можно добавить ^, для указания что и спереди ничего не должно быть

^(a|b|c)*cc$

небольшое отступление: цикл

for (int i= 0;i<alphabet.Length;i++) 
{ 
    regex += alphabet[i]; 
    if (i != alphabet.Length - 1) regex += '|'; 
}

Легко меняется на string.Join: string.Join("|", alphabet)

И общая сборка выражения упрощается до:

regex = `({string.Join("|", alphabet)})*{finalChars}`;