获取匹配模式的行号
本文关键字:模式 获取 | 更新日期: 2023-09-27 18:17:44
我使用此代码检查加载到内存中的文本文件中是否存在字符串
foreach (Match m in Regex.Matches(haystack, needle))
richTextBox1.Text += "'nFound @ " + m.Index;
正则表达式返回发生匹配的位置,但我想要知道行号吗?
最好的解决方案是调用一个仅在发生匹配时才获取行号的方法。这样,如果检查了多个文件并且带有'n
的正则表达式将起作用,则性能不会受到太大影响。在堆栈溢出的某个地方找到了此方法:
public int LineFromPos(string input, int indexPosition)
{
int lineNumber = 1;
for (int i = 0; i < indexPosition; i++)
{
if (input[i] == ''n') lineNumber++;
}
return lineNumber;
}
您可以
先将文本拆分为几行,然后将正则表达式应用于每一行 - 当然,如果needle
包含换行符,则不起作用:
var lines = haystack.Split(new[] { Environment.NewLine }, StringSplitOptions.None);
for(int i=0; i <lines.Length; i++)
{
foreach (Match m in Regex.Matches(lines[i], needle))
richTextBox1.Text += string.Format("'nFound @ line {0}", i+1)
}
为此,我做了以下工作...
- 将文件内容读入缓冲区
-
使用正则表达式匹配文件中的所有回车符,并注意回车列表中有索引
private static List<CarriageReturn> _GetCarriageReturns( string data ) { var carriageReturns = new List<CarriageReturn>(); var carriageReturnRegex = new Regex( @"(?:(['n]+?))", RegexOptions.IgnoreCase | RegexOptions.Singleline ); var carriageReturnMatches = carriageReturnRegex.Matches( data ); if( carriageReturnMatches.Count > 0 ) { carriageReturns.AddRange( carriageReturnMatches.Cast<Match>().Select( match => new CarriageReturn { Index = match.Groups[1].Index, } ).ToList() ); } return carriageReturns; }
-
在文件上使用我的正则表达式,对于每场比赛都做这样的事情
LineNumber = carriageReturns.Count( ret => ret.Index < match.Groups[1].Index ) + 1
所以基本上我计算比赛前发生的回车次数并加 1
foreach (Match m in Regex.Matches(haystack, needle))
{
int startLine = 1, endLine = 1;
// You could make it to return false if this fails.
// But lets assume the index is within text bounds.
if (m.Index < haystack.Length)
{
for (int i = 0; i <= m.Index; i++)
if (Environment.NewLine.Equals(haystack[i]))
startLine++;
endLine = startLine;
for (int i = m.Index; i <= (m.Index + needle.Length); i++)
if (Environment.NewLine.Equals(haystack[i]))
endLine++;
}
richTextBox1.Text += string.Format(
"'nFound @ {0} Line {1} to {2}", m.Index, startLine, endLine);
如果指针越过一条线,实际上不会起作用,但那是因为正则表达式无法识别这一点。
编辑 也许你可以用空格替换文本中的结束行并在那里应用正则表达式,这段代码仍然有效,如果指针落在一行上,它仍然会被发现:
Regex.Matches(haystack.Replace(Environment.NewLine, " "), needle)