【问题标题】:Discard match if it doesn't contain a specified keyword如果匹配项不包含指定的关键字,则放弃匹配项
【发布时间】:2018-03-12 23:41:16
【问题描述】:

示例文本:

START
This is example example example example example example example example .
END
START
This is example 1234 14 756 214 6456 5 2 4234 66 match.
END
START
This is This isThis isThis isThis isThis isThis isThis isThis is.
END

我只需要匹配“START”和“END”关键字之间且包含“match”字样的文本。

我目前有这个正则表达式:

Regex.Matches(myString, @"START(.*?match.*?)END", RegexOptions.Singleline);

它不能正常工作,因为它在匹配“END”关键字之前等待“匹配”单词出现:

This is example example example example example example example example .
END
START
This is example 1234 14 756 214 6456 5 2 4234 66 match.

如果“START”和“END”关键字之间的句子不包含“match”字样,我该如何舍弃它们?

【问题讨论】:

  • "RegexOptions.Singleline" - 考虑到您的示例输入和模式,这似乎不正确。
  • @Fildor 也许阅读docs.microsoft.com/en-us/dotnet/standard/base-types/… 可能会让您明白为什么它不像看起来那么奇怪。
  • @spender 正确,不像看起来那么奇怪……不过我还是不会在这里使用它。

标签: c# regex


【解决方案1】:

您需要防止正则表达式引擎跨越匹配边界;惰性量词不会这样做,但 negative lookahead assertion 可以:

Regex.Matches(myString, @"START((?:(?!\bEND\b).)*match(?:(?!\bEND\b).)*)END", RegexOptions.Singleline);

测试它live on regex101.com

(?:(?!\bEND\b).)* 匹配任何字符 (.),但前提是它不是以 END 关键字 (?!\bEND\b) 开头的。通过将其包含在重复的非捕获组(?:...)* 中,我们可以确保在每个字符上都测试此条件。

【讨论】:

    【解决方案2】:

    我得出了这个解决方案,它似乎比其他解决方案更简单。它允许除单词 END 之外的任何字符(在这种情况下,. 还包括换行符,但这就是 singleline 的用途)

    START((?!END).)*match((?!END).)*END
    

    【讨论】:

    • 感谢您的帮助。你的解决方案也有效,但我只能接受一个答案:(。
    【解决方案3】:

    您确定要对此类任务使用正则表达式吗?您可以通过以下方式解决它:

            string mystring = "START This is example example example example example example example example. END START This is example 1234 14 756 214 6456 5 2 4234 66 match. END START This is This isThis isThis isThis isThis isThis isThis isThis is. END";
            string result = "";
    
            foreach(string text in mystring.Split(new string[] { "START", "END" }, StringSplitOptions.RemoveEmptyEntries))
            {
                if (text.Trim().Contains("match"))
                {
                    result = text;
                }
            }
    

    【讨论】:

    • 感谢您的帮助。我知道可以这样做,但我需要使用正则表达式。
    猜你喜欢
    • 2017-06-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多