获取匹配模式的行号

时间:2011-12-11 22:47:40

标签: c# regex

我使用此代码检查我加载到内存

的文本文件中是否存在字符串
foreach (Match m in Regex.Matches(haystack, needle))
    richTextBox1.Text += "\nFound @ " + m.Index;

正则表达式返回匹配发生但我想要的位置 知道行号?

4 个答案:

答案 0 :(得分:6)

最佳解决方案是调用仅在匹配发生时获取行号的方法。 这样,如果检查了多个文件并且\n的正则表达式将起作用,则性能不会受到太大影响。在stackoverflow上找到了这个方法:

    public int LineFromPos(string input, int indexPosition)
    {
        int lineNumber = 1;
        for (int i = 0; i < indexPosition; i++)
        {
            if (input[i] == '\n') lineNumber++;
        }
        return lineNumber;
    }

答案 1 :(得分:5)

您可以先将文本拆分为行,然后将RegEx应用于每一行 - 当然,如果needle包含NewLine,则不起作用:

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)
}

答案 2 :(得分:0)

    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)

答案 3 :(得分:0)

为此,我执行了以下操作...

  • 将文件内容读入缓冲区
  • 使用正则表达式匹配文件中的所有回车符,并注意回车符列表中的索引

    私有静态列表_GetCarriageReturns(字符串数据)     {         var运输返回=新的List();

        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