如何以开始模式查找字符串并包含模式

时间:2019-01-10 17:50:56

标签: c# regex

我一直在研究this post,试图将ac#正则表达式放在一起以执行以下操作:查找一个字符串是否包含另一个以某些字母开头并包含某些字符的字符串。 < / p>

这是干草堆字符串的1个具体示例:

NOT SUPPCODE{900mm,1500mm} and IDU{true}

我需要发现haystack字符串是否包含NOT(最好不区分大小写),后跟1个空格,然后紧跟一个不间断的空格“ word”,该单词包含以下3个字符(按顺序,但不相邻):{,}。换句话说,左/右花括号必须包含一个或多个逗号。 大括号内的空格很好,但SUPPCODE(在此示例中)和左大括号之间不得有空格。

我的干草堆示例实际上与该模式匹配,因为有一个NOT(不需要在字符串的开头),后跟一个空格,然后是一系列包含左花括号,逗号和右花括号。这三个字符将不相邻。

这是我根据上面提到的帖子放在一起的C#代码,对我不起作用:

public static bool ContainsRegex(string haystack, string startsWith, string contains) {
   var regex = new Regex("(?=.*" + contains + ")^" + startsWith);
   int matches = regex.Matches(haystack).Count;
   return matches > 0;
}

这样称呼:

bool isFound = ContainsRegex("NOT SUPPCODE{900mm,1500mm} and IDU{true}", "NOT ", "{,}");

那些字符串参数当然是动态的,并且在运行时总是不同的。

即使在应该返回true的情况下(如上所示),我的函数也始终返回false。

以下是一些否定测试的字符串,它们应该返回false:

SUPPCODE{900mm,1500mm} and IDU{true} // doesn't begin with NOT
STUFF SUPPCODE{900mm,1500mm} and IDU{true} // doesn't begin with NOT
NOT SUPPCODE{900mm} and IDU{true} // no comma between curly braces
NOT SUPPCODE,5,6900mm} and IDU{true} // no left curly brace
NOTSUPPCODE{900mm,1500mm} and IDU{true} // no space between NOT and SUPPCODE
NOT SUPPCODE {900mm,1500mm} and IDU{true} // space between SUPPCODE and left curly brace

我在做什么错了?

1 个答案:

答案 0 :(得分:2)

您可以使用

public static bool ContainsRegex(string haystack, string startsWith, string contains) 
{
    var delims = contains.Select(x => x.ToString().Replace("\\", @"\\").Replace("-", @"\-").Replace("^", @"\^").Replace("]", @"\]")).ToList();
    var pat = $@"^{startsWith} \w+{Regex.Escape(contains.Substring(0,1))}[^{string.Concat(delims)}]*{Regex.Escape(contains.Substring(1,1))}[^{delims[0]}{delims[2]}]*{Regex.Escape(contains.Substring(2,1))}";
    // Console.WriteLine(pat); // => ^NOT \w+\{[^{,}]*,[^{}]*}
    return Regex.IsMatch(haystack, pat, RegexOptions.IgnoreCase);
}

这里是an example

var strs = new[] { "SUPPCODE{900mm,1500mm} and IDU{true}",
            "STUFF SUPPCODE{900mm,1500mm} and IDU{true}",
            "NOT SUPPCODE{900mm} and IDU{true}",
            "NOT SUPPCODE,5,6900mm} and IDU{true}",
            "NOTSUPPCODE{900mm,1500mm} and IDU{true}",
            "NOT SUPPCODE {900mm,1500mm} and IDU{true}",
            "NOT SUPPCODE{900mm,1500mm} and IDU{true}"};
foreach (var s in strs)
    Console.WriteLine($"{s} => {ContainsRegex(s, "NOT", "{,}")}");

输出:

SUPPCODE{900mm,1500mm} and IDU{true} => False
STUFF SUPPCODE{900mm,1500mm} and IDU{true} => False
NOT SUPPCODE{900mm} and IDU{true} => False
NOT SUPPCODE,5,6900mm} and IDU{true} => False
NOTSUPPCODE{900mm,1500mm} and IDU{true} => False
NOT SUPPCODE {900mm,1500mm} and IDU{true} => False
NOT SUPPCODE{900mm,1500mm} and IDU{true} => True

假设contains参数仅包含3个字符:起始定界符是第一个,中间的是内部的强制性字符,然后第三个字符是结尾的字符。

另请参阅resulting regex demo

详细信息

  • ^-字符串的开头
  • NOT-startsWith字符串
  • -空格
  • \w+-1个以上的字符字符
  • \{-起始定界符
  • [^{,}]*-除定界符外的0+个字符
  • ,-中间必填字符
  • [^{}]*-除开始和结束定界符以外的0+个字符
  • }-尾部定界符。