使用正则表达式在列表中查找两个字符串

时间:2016-11-20 03:46:57

标签: c# regex

我需要在列表中找到两个字符串,其中包含另一个字符串中的字符,这些字符串不是有序的。为了说清楚,一个例子可以是动物列表,如:

lion
dog
bear
cat

给定的字符串是:oodilgn

这里的答案是:liondog

字符串中的每个字符只能使用一次。

是否有正则表达式允许我这样做?

3 个答案:

答案 0 :(得分:0)

您可以尝试将给定字符串放在[]之间。这些括号将允许以任何顺序从这些字母中选择。这可能不是一个完美的解决方案,但它会占据你的大部分名单。

例如,您可以将oodilgn写为[oodilgn],然后使用大括号{}添加要找到的最小字母数 - 假设为3。完整的正则表达式将是这样的:

[oodilgn]{3,}

此代码基本上是这样说:找到任何包含三个字母的单词,这些字母位于括号之间。

演示:https://regex101.com/r/MCWHjQ/2

答案 1 :(得分:0)

请试一试

Regex r=new Regex("^[.*oodilgn]$");
        var list=new List<String>(){"lion","dog","fish","god"};
        var output=list.Where(x=>r.IsMatch(x));

<强>结果

output=["lion","dog","god"];

答案 2 :(得分:0)

这是一些完成工作的示例算法。我假设两个字符串在一起不需要从文本中取出所有字母,否则我会进行额外的评论检查。我还要先回答两个合适的答案。 以下是您在外部函数Main中调用它的方式,或者:

static void Main(string[] args)
{
    var text = "oodilgn";
    var listOfWords = new List<string> { "lion", "dog", "bear", "cat" };
    ExtractWordsWithSameLetters(text, listOfWords);
}

这是算法的功能。所有字符串制作都完全使用正则表达式。

    public static void ExtractWordsWithSameLetters(string text, List<string> listOfWords)
    {
        string firstWord = null;
        string secondWord = null;
        for (var i = 0; i < listOfWords.Count - 1; i++)
        {
            var textCopy = text;
            var firstWordIsMatched = true;
            foreach (var letter in listOfWords[i])
            {
                var pattern = $"(.*?)({letter})(.*?)";
                var regex = new Regex(pattern);
                if (regex.IsMatch(text))
                {
                    textCopy = regex.Replace(textCopy, "$1*$3", 1);
                }
                else
                {
                    firstWordIsMatched = false;
                    break;
                }
            }

            if (!firstWordIsMatched)
            {
                continue;
            }
            firstWord = listOfWords[i];

            for (var j = i + 1; j < listOfWords.Count; j++)
            {
                var secondWordIsMatched = true;
                foreach (var letter in listOfWords[j])
                {
                    var pattern = $"(.*?)({letter})(.*?)";
                    var regex = new Regex(pattern);
                    if (regex.IsMatch(text))
                    {
                        textCopy = regex.Replace(textCopy, "$1*$3", 1);
                    }
                    else
                    {
                        secondWordIsMatched = false;
                        break;
                    }
                }
                if (secondWordIsMatched)
                {
                    secondWord = listOfWords[j];
                    break;
                }
            }

            if (secondWord == null)
            {
                firstWord = null;
            }
            else
            {
                //if (textCopy.ToCharArray().Any(l => l != '*'))
                //{
                //    break;
                //}
                break;
            }
        }

        if (firstWord != null)
        {
            Console.WriteLine($"{firstWord} { secondWord}");
        }
    }

功能远未优化,但可以满足您的需求。如果您想要返回结果,而不是打印它们,只需创建一个数组并在其中添加firstWordsecondWord并返回类型string[]或添加两个ref out的参数。您需要在调用函数中检查结果。