我有一个单词列表,我需要消除java.exe
出现零次或不超过一次的所有单词,i
出现零次或不超过两次,且不超过0次三次出现o
。
例如:
u
可行,但in
不会。
inside
和on
会有用,但octopus
不会
到目前为止,我最好的猜测似乎并没有完成任务:
commotion
答案 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*
\b
匹配word boundary (?:
打开非捕获group (?>
打开atomic group \w
匹配word character