尝试多次匹配多个单词,使用正则表达式按任意顺序匹配

本文关键字:正则表达式 顺序 任意 单词 | 更新日期: 2023-09-27 17:59:02

我正在检查文本是否包含两个或多个特定单词。单词可以按任何顺序出现,可以多次出现在文本中,但至少出现一次。

如果文本匹配,我将需要获得有关单词位置的信息。

假设我们有文本:"有一次我去了一家商店,花了一美元买了一杯可乐,然后我又免费得到了一杯"

在这个例子中,我想匹配单词coke和dollar。因此,结果应该是:焦炭:指数37,长度4美元:指数48,长度6焦炭:指数84,长度4

我已经有了这个:(我认为这有点错误,因为它应该至少包含每个单词一次,所以+应该在那里而不是*)

(?:('bcoke'b))'*(?:('bdollar'b))'*

但是,如果我让regex Buddy突出显示第1组和第2组,那么它会突出显示这三个单词。

但是当我在C#中运行这个程序时,我不会得到任何结果。

你能给我指正确的方向吗?

尝试多次匹配多个单词,使用正则表达式按任意顺序匹配

我认为只使用正则表达式是不可能的。以下是使用正则表达式和linq:的可能解决方案

var words = new HashSet<string>(StringComparer.OrdinalIgnoreCase) { "coke", "dollar" };
var regex = new Regex(@"'b(?:"+string.Join("|", words)+@")'b", RegexOptions.IgnoreCase);
var text = @"Once I went to a store and bought a coke 
for a dollar and I got another coke for free";
var grouped = regex.Matches(text)
    .OfType<Match>()
    .GroupBy(m => m.Value, StringComparer.OrdinalIgnoreCase)
    .ToArray();
if (grouped.Length != words.Count)
{
    //not all words were found
}
else
{
    foreach (var g in grouped) 
    {
        Console.WriteLine("Found: " + g.Key);
        foreach (var match in g) 
            Console.WriteLine("    At {0} length {1}", match.Index, match.Length);
    }
}

输出:

Found: coke
    At 36 length 4
    At 72 length 4
Found: dollar
    At 47 length 6

怎么样,它很糟糕,但我认为它有机会工作它是纯RegEx,没有额外的工具。

(?:^|'W)[cC][oO][kK][eE](?:$|'W)|(?:^|'W)[dD][oO][lL][lL][aA][rR](?:$|'W)

如果你想让它捕获cokeDollardollarCoKe等,就去掉'w