Reputation: 947
This one should be simple, but it is stumping me.
I have a Regex that could have a match. If it does, I want to know what line it is on. Is there a simple way to do this maybe with Linq without looping through each of the lines counting the characters?
Regex rx = new Regex(myRegEx, RegexOptions.Compiled | RegexOptions.IgnoreCase);
string[] docLines = File.ReadAllLines(myDocPath);
// Find matches
MatchCollection matches = rx.Matches(string.Join(Environment.NewLine, docLines));
if(matches.Count > 0)
{
long loc = matches[0].Index;
//Find the Line
}
Upvotes: 1
Views: 135
Reputation: 2862
Runfastman,
You can do this by using LINQ combined with an index like so:
using System.Linq;
using System.Text.RegularExpressions;
var rx = new Regex(myRegEx, RegexOptions.Compiled | RegexOptions.IgnoreCase);
var docLines = File.ReadAllLines(myDocPath);
var matchLine = docLines.Select((line, index) => new { line, index }).FirstOrDefault(l => rx.IsMatch(l.line));
if(matchLine != null) Console.WriteLine($@"Match line # = {matchLine.index}");
While it is true (as others have mentioned) that the compiler iterates over the lines to accomplish the task, I sense that the above is what you had in mind.
EDIT
In light of your comment that the target string could span multiple lines, I would do the following:
var rx = new Regex(myRegEx, RegexOptions.Compiled | RegexOptions.IgnoreCase);
//Read all text into a variable.
var docLines = File.ReadAllText(myDocPath);
//Check that there is, in fact, a match.
if(!rx.IsMatch(docLines)) return;
//Split your text blob by that match.
var rxSplit = rx.Split(docLines);
//Then count the number of line brakes before the match.
var startOfMatchLine = new Regex(@"(\n|\r\n?)").Matches(rxSplit[0]).Count;
//And print the result.
Console.WriteLine($@"{startOfMatchLine}");
Upvotes: 1
Reputation: 12378
You can find the line by using match.Value
, for example :
Regex rx = new Regex("b", RegexOptions.Compiled | RegexOptions.IgnoreCase);
string[] docLines = new[] { "zzazz", "zzbzz", "zzczz", "zzzzz" };
// Find matches
MatchCollection matches = rx.Matches(string.Join(Environment.NewLine, docLines));
if (matches.Count > 0)
{
string loc = matches[0].Value;
//Find the Line
var line = docLines.FirstOrDefault(x => x.Contains(loc));
}
Upvotes: -1
Reputation: 74605
You can match line by line:
Regex rx = new Regex(myRegEx, RegexOptions.Compiled | RegexOptions.IgnoreCase);
string[] docLines = File.ReadAllLines(myDocPath);
// Find matches
for(int x = 0; x < docLines.Length; x++){
string line = docLines[x];
if(rx.IsMatch(line))
Console.Write($"Match on line {x}");
}
Upvotes: 1