选择包含局部关键字的引号之间的所有内容

时间:2019-01-30 09:07:07

标签: c# regex

我想检索与部分关键字匹配的引号之间的完整字符串。

假设我有一个关键字(即example-a),它是目录结构(即"/tutorial/example/example-a/")的一部分。

我尝试过"(.*?)",它返回示例输入中引号之间的所有字符串实例。我不喜欢必须迭代MatchCollection来查找它是否包含目标关键字的想法,因为我当前的匹配大约是1700+。我可以将MatchCollection投射到一个列表中,然后在捕获组包含该关键字的情况下进行查询,然后进行查询。

所以我的期望是,对于输入"/tutorial/example/example-a/",我可以为关键字传递任何字符串,在这种情况下为example-a,并在引号/tutorial/example/example-a/内返回值。 / p>

有没有办法在单个正则表达式中实现这一目标?还是更好的方法来达到我想要的结果?

2 个答案:

答案 0 :(得分:1)

您可以利用正则表达式的“ lookhead”功能,例如在模式中

"([^"]*(?=example-a)[^"]*)"

我们匹配双引号,后跟除右双引号之外的任何内容,但是部分(?=example-a)(肯定的lookeahad断言)告诉您仅在{{1}之前找到example-a时才继续匹配}匹配右引号。这称为零长度断言,因为它不会向匹配的字符添加任何内容,但可以控制是否匹配。引号旁边的"(捕获其中的部分。

https://regex101.com/r/bUd8lf/2/

答案 1 :(得分:1)

使用迭代器编写自己的自定义拆分器并不难。

如果您需要更改或有任何疑问,请告诉我。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApp1
{
    class Program
    {
        static IEnumerable<string> Split(string text, char splitChar, bool skipEmpty)
        {
            StringBuilder between = new StringBuilder();

            bool inside = false;

            foreach (char c in text)
            {
                if (c == splitChar)
                {
                    if (inside)
                    {
                        if (between.Length != 0 || !skipEmpty)
                            yield return between.ToString();

                        inside = false;
                    }
                    else
                    {
                        between.Clear();
                        inside = true;
                    }

                    continue;
                }

                between.Append(c);
            }
        }

        static void Main(string[] args)
        {
            string text = "\"/tutorial/example/example-a/\" aaa \"/tutorial/example/example-b/\" bbb \"/tutorial1/example1/example-a/\" ccc \"\" \"";

            string search = "example-A";

            Console.WriteLine("All results:");
            Console.WriteLine();
            foreach (string item in Split(text, '"', skipEmpty: true))
            {
                Console.WriteLine(item);
            }

            Console.WriteLine();
            Console.WriteLine();

            Console.WriteLine($"Search results of '{search}' case-insensitive:");
            Console.WriteLine();
            foreach (string item in Split(text, '"', skipEmpty: true).Where(i => i.IndexOf(search, StringComparison.OrdinalIgnoreCase) != -1))
            {
                Console.WriteLine(item);
            }

            Console.ReadKey();
        }
    }
}