【问题标题】:c# RegEx what line is the match on. Linq?c# RegEx 匹配在哪一行。林克?
【发布时间】:2021-04-10 18:12:34
【问题描述】:

这个应该很简单,但是难住了。

我有一个可以匹配的正则表达式。如果是这样,我想知道它在哪条线上。有没有一种简单的方法可以用 Linq 做到这一点,而不用遍历每一行来计算字符?

  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
  }

【问题讨论】:

  • 请注意,Regex 或 LINQ 无论如何都会遍历字符和行。

标签: c# regex linq


【解决方案1】:

跑步者,

您可以通过将 LINQ 与如下索引结合使用来做到这一点:

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

虽然编译器确实(正如其他人提到的那样)迭代行来完成任务,但我感觉上面是您的想法。

编辑

鉴于您对目标字符串可能跨越多行的评论,我将执行以下操作:

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

【讨论】:

  • 我认为如果 RegEx 跨越多行,这也会有问题,那么它就不会找到它。我对 LINQ 不太擅长,但它不能计算每行的字符数,直到它到达正确的索引?
  • @runfastman,我根据您的评论更新了我的答案。
  • 我什至没想过只计算换行符,这么简单。谢谢。
【解决方案2】:

你可以逐行匹配:

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

【讨论】:

  • 如果 RegEx 跨越多行,那么它不会找到匹配项。
  • 更具体地说明您的示例数据和正则表达式模式,以便将这一要求考虑在内?
【解决方案3】:

您可以使用match.Value 查找该行,例如:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-12
    • 2020-09-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多