获得Regex匹配的整条线

时间:2013-08-22 14:20:39

标签: c# regex

我有一些多行文字,我想找到包含特定单词的行。

在目前的实现中,我只得到了这个词,但我希望得到整行。这是代码:

var finder = new Regex(@"(^|\W)" + Regex.Escape(wordToFind) + @"(\W|$)", RegexOptions.IgnoreCase);
 foreach (var match in finder.Matches(multilineString))
 {
      //match should be the whole line
 }

示例:

If Request.QueryString("bar") <> "" Then
    Set bar= foo("baz")
Else
    Set bar= foo("baz2")
End If

如果我找foo,我应该得到:

Set bar= foo("baz")
Set bar= foo("baz2")

我没有实现正则表达式,我对正则表达式不是很熟悉,如果有人能给我一些提示继续进行调查,我将不胜感激。

由于

3 个答案:

答案 0 :(得分:1)

您可以尝试使用此正则表达式:

Regex regex = new Regex(@"^.*?\W" + Regex.Escape(wordToFind) + @"\W.*?$");

^匹配字符串或行的开头,末尾的$匹配字符串或行的结尾。
.*?匹配所有内容(但尽可能少),\W(大写“W”)匹配任何非单词字符(既不是字母也不是数字的字符)。

如果您希望单词仅用空格分隔,则可以使用\s(小写“s”)代替\W

Here is a good reference for Regex

答案 1 :(得分:0)

你可以这样做

string[] lines = multilinestring.Split(new string[] { Environment.NewLine }, StringSplitOptions.None);
List<string> validString = new List<string>();
foreach(string s in lines)
{
   if(finder.Match(s).Success)
   {
      validString.Add(s);
   }
}

尝试一下,应该工作

List<string> lines = multilinestring.Split(new string[] { Environment.NewLine }, StringSplitOptions.None).ToList();
List<string> validString =  lines.Where(x => finder.IsMatch(x)).ToList();

答案 2 :(得分:0)

Nolonar's solution does not take into account一行以所需单词开头或结尾的可能性。

此外,您需要记住^$锚点与整个 string 的开始/结尾匹配,除非您通过RegexOptions.Multiline选项进行设置它们匹配 line 边界。

因此,提取包含整个单词的所有行的正确的仅使用正则表达式的解决方案是

var finder = new Regex($@"^.*?(?<!\w){Regex.Escape(wordToFind)}(?!\w).*", RegexOptions.IgnoreCase | RegexOptions.Multiline);
// Or, in order to avoid getting CR at the end of the extracted lines
// var finder = new Regex($@"^.*?(?<!\w){Regex.Escape(wordToFind)}(?!\w)[^\r\n]*", RegexOptions.IgnoreCase | RegexOptions.Multiline);
var results = finder.Matches(multilineString).Cast<Match>().Select(x => x.Value); // Use x.Value.Trim() to trim the result

请注意,您可以通过使用内联修饰符RegexOptions.IgnoreCase | RegexOptions.Multiline(?im)合并到模式本身中来“缩小”代码:

var finder = new Regex($@"(?im)^.*?(?<!\w){Regex.Escape(wordToFind)}(?!\w).*");
var finder = new Regex($@"(?im)^.*?(?<!\w){Regex.Escape(wordToFind)}(?!\w)[^\r\n]*"); 
                          ^^^^^

请参见regex demo

模式详细信息

  • ^-一行的开头
  • .*?-除换行符以外的任何0+个字符,并且尽可能少(*?是一个懒惰的,非贪婪的量词)
  • (?<!\w)-左侧单词边界
  • {Regex.Escape(wordToFind)}-wordToFind字符串的转义版本
  • (?!\w)-右侧单词边界
  • .*-尽可能多的除换行符以外的0+个字符(*是贪婪的量词)。 注意.与.NET正则表达式中的回车符\r匹配,因此,我建议.Trim()提取值。或者使用[^\r\n]*来匹配0个或多个CR和LF以外的字符。