正则表达式强制字符串中特定字符的上限

时间:2015-11-21 16:46:59

标签: c# regex

我有一个单词列表,我需要消除java.exe出现零次或不超过一次的所有单词,i出现零次或不超过两次,且不超过0次三次出现o

例如:

u可行,但in不会。

insideon会有用,但octopus不会

到目前为止,我最好的猜测似乎并没有完成任务:

commotion

3 个答案:

答案 0 :(得分:2)

您的正则表达式仅检查后续字符,例如uuu。所以这不起作用。通常使用正则表达式有点困难,因为您必须运行三个独立的正则表达式来检查每个字符,或者您必须指定这些字符之间的每个可能的顺序组合。

相反,考虑在没有正则表达式的情况下解决此问以下解决方案非常直接,并通过迭代最多迭代检查每个字符串:

List<string> words = new List<string> { "in", "inside", "on", "octopus", "commotion" };

var result = words.Where(x =>
{
    var maxCounts = new Dictionary<char, int>{ { 'i', 1 }, { 'o', 2 }, { 'u', 3 } };
    foreach (char c in x)
    {
        if (maxCounts.ContainsKey(c))
        {
            maxCounts[c]--;
            if (maxCounts[c] < 0)
                return false;
        }
    }
    return true;
}).ToArray();

答案 1 :(得分:2)

string[] text = new string[] { "in", "inside", "on", "octopus", "commotion" };

Regex regex = new Regex(@"(i.*){2}|(o.*){3}|(u.*){4}");
var lines = text.Where(x => !regex.IsMatch(x)).ToArray(); // text is array containing the words 
foreach (var s in lines)
{
    Console.WriteLine(s);
}

修改

只有一个警告。由于回溯,该解决方案不会扩展到大量字母。为了改进缩放,必须禁用回溯:

Regex regex = new Regex(@"(?>.*?i){200}|(?>.*?o){300}|(?>.*?u){400}");

答案 2 :(得分:2)

可以使用简单的正则表达式进行3 |次更改。

如果输入是一个单词,则进行匹配。

i.*?i|o(?:.*?o){2}|u(?:.*?u){3}

或者用于匹配文字中的单词。

\b(?:(?>\w*?i){2}|(?>\w*?o){3}|(?>\w*?u){4})\w*

See demo at regexhero