Obtain the line number for matched pattern

To do this I did the following...

  • Read file contents into buffer
  • Use regex to match all carriage returns in the file and note there index in a list of carriage returns

    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;
    }
    
  • Use my regex on the file and for every match do something like this LineNumber = carriageReturns.Count( ret => ret.Index < match.Groups[1].Index ) + 1

So basically I count the carriage returns occurring before my match and add 1


You can split your text into lines first and apply your RegEx to each line - of course that doesn't work if needle contains a 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)
}

The best solution would be to call a method that gets the line number only if a match occurs. This way the performance is not much affected if multiple files were checked and the regexp with \n will work. Found this method somewhere on 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;
    }

Tags:

C#

Regex