使用Regex检查多个单词是否匹配[已关闭]

gr8qqesn  于 2022-12-24  发布在  其他
关注(0)|答案(2)|浏览(135)

十小时前关门了。
Improve this question
我正在寻找一个RegExp,它检查是否有2个或更多的单词出现在一个字符串中,而不管它们的顺序。
如果我想找到单词"dog"和"cat",表达式必须只在它们都在句子中时才能找到匹配项:
"我喜欢狗"-不匹配
"我爱猫"-不匹配
"我有一只狗和一只猫"-好的
我找到的唯一真正的解决方案是循环单词,将它们作为模式传递给Regex.IsMatch,但我希望在这种情况下有更好的方法使用regex。
代码:

string[] patterns = RefinedQuery.Split(" ");
bool checkPatterns(string test, string[] ps, int i)
{
     if(i > ps.Length - 1)
     {
         return true;
     }
     return Regex.IsMatch(test, ps[i], RegexOptions.IgnoreCase) && checkPatterns(test, ps, i+1);
}
return workers.Where(delegate(WorkerExpanded worker)
{
    string fullname = worker.ToDisplayString();
    return checkPatterns(fullname, patterns, 0);
});

我不想循环单词列表并使用regex.isMatch或string.contains,而是想找到一个更有效的解决方案。

wgmfuz8q

wgmfuz8q1#

本例中的正则表达式模式将匹配句子中的"dog"和"cat"。它通过使用|运算符的交替来实现这一点,该运算符允许"dog"或"cat"出现在第一个和第二个位置。这意味着该模式将匹配诸如"I own a dog and a cat"和"I own a cat and a dog"之类的句子。
演示:https://dotnetfiddle.net/pU2HhD
实施:

List<string> sentences = new List<string>
{
    "I like dogs",
    "I love cats",
    "I own a dog and a cat",
    "I own a cat and a dog"
};

string pattern = @"\b(dog|cat)\b.*\b(dog|cat)\b";

foreach (var sentence in sentences) 
{
    Match match = Regex.Match(sentence, pattern);
    if (match.Success)
        Console.WriteLine($"{sentence} - ok");
    else
        Console.WriteLine($"{sentence} - no match");
}

输出:

I like dogs - no match
I love cats - no match
I own a dog and a cat - ok
I own a cat and a dog - ok

使用List个单词的备选答案:
Regex.Escape方法用于对单词中的任何特殊字符进行转义,以便将它们视为正则表达式中的原义字符。\b转义序列用于匹配单词边界,从而确保将单词作为完整的单词进行匹配,而不是作为其他单词的子字符串进行匹配。
演示:https://dotnetfiddle.net/9djbw1

var words = new HashSet<string> { "cat", "dog", "bird"};

HashSet<string> sentences = new HashSet<string>
{
    "I own a dog and a cat",
    "I own a cat, a bird and a dog"
};

var pattern = @"(?=.*\b" + string.Join(@"\b).*(?=.*\b", 
    words.Select(Regex.Escape)) + @"\b).*";

// The regular expression is compiled to an intermediate language (IL) code,
// which can be faster to execute than interpreting the regular expression at runtime.
// Recommended if expression will be used frequently
var regex = new Regex(pattern, RegexOptions.Compiled);

foreach (var sentence in sentences) 
{
    if (regex.IsMatch(sentence))
        Console.WriteLine("Matched all words");
    else
        Console.WriteLine("Not matched");
}

输出:

Not matched
Matched all words
vsnjm48y

vsnjm48y2#

^.*(dog).*(cat)|.*(cat).*(dog).*$

这个应该可以了。
.*(dog).*(cat)第一部分检查字符串是否在“cat”之前包含“dog”
.*(cat).*(dog).*第二部分检查字符串是否在“dog”之前包含“cat”
|是用于OR的逻辑运算符
^$是锚点,与起点和终点匹配

相关问题