在Regex匹配的地方获得整条线
本文关键字:方获得 Regex | 更新日期: 2023-09-27 18:28:48
我有一些多行文本,我想找到包含特定单词的行。
在当前的实现中,我只得到单词,但我想得到整行。这是代码:
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")
我没有实现正则表达式,也不太熟悉正则表达式,如果有人能给我一些提示,让我继续研究,我将不胜感激。
感谢
您可以尝试使用以下正则表达式:
Regex regex = new Regex(@"^.*?'W" + Regex.Escape(wordToFind) + @"'W.*?$");
^
与字符串或行的开头匹配,末尾的$
与字符串或线的末尾匹配.*?
匹配所有字符(但尽可能少),'W
(大写"W")匹配任何非单词字符(既不是字母也不是数字的字符)。
或者,如果您希望单词仅由空格分隔,则可以使用's
(小写"s")而不是'W
。
这是Regex的一个很好的参考。
你可以这样做
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();
Nolonar的解决方案没有考虑一行以所需单词开头或结尾的可能性。
此外,您需要记住,^
和$
锚与整个字符串的开始/结束匹配,除非您通过RegexOptions.Multiline
选项使它们与行边界匹配。
因此,提取包含一个完整单词的所有行的正确的仅正则表达式解决方案是
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
请注意,您可以通过使用内联修饰符、(?im)
:将RegexOptions.IgnoreCase | RegexOptions.Multiline
合并到模式本身来"收缩"代码一点
var finder = new Regex($@"(?im)^.*?(?<!'w){Regex.Escape(wordToFind)}(?!'w).*");
var finder = new Regex($@"(?im)^.*?(?<!'w){Regex.Escape(wordToFind)}(?!'w)[^'r'n]*");
^^^^^
查看regex演示
图案详细信息
^
—线路起点.*?
-除了换行符之外的任何0+个字符,尽可能少(*?
是一个懒惰的、非贪婪的量词)(?<!'w)
-左侧单词边界{Regex.Escape(wordToFind)}
-wordToFind
字符串的转义版本(?!'w)
-右侧单词边界.*
-除了换行符之外的任何0+个字符,尽可能多(*
是贪婪的量词)注意:.
与.NET正则表达式中的回车'r
匹配,因此我建议.Trim()
使用提取的值。或者使用[^'r'n]*
来匹配除CR和LF之外的0个或多个字符