搜索单词并找到它的行号 LINQ

Searching for word and finding it's line number LINQ

大家好,我发现了以下代码 HERE,想知道是否可以通过使用 LINQ 查询或其他方式获取单词出现的行号?

Dim startFolder = "C:\Users\me\Documents\Visual Studio 2012\Projects\project"
Dim fileList = New System.IO.DirectoryInfo(startFolder).GetFiles("*.vb", System.IO.SearchOption.AllDirectories)
Dim queryMatchingFiles = From file In fileList _
                             Where file.Extension = ".vb" _
                             Let fileText = GetFileText(file.FullName) _
                             Where fileText.Contains(word2Search) _
                             Select file.FullName

Debug.Print("The term " & word2Search & " was found in:")

For Each filename In queryMatchingFiles
    Debug.Print(filename)
Next

该代码可用于查找单词,但我真的很想知道它是在哪一行找到的。

任何帮助都会很棒!

LINQ Select 方法 has a overload 传入项的索引。

Dim startFolder = "C:\Users\me\Documents\Visual Studio 2012\Projects\project"
Dim matches =
    From f In Directory.EnumerateFiles(startFolder, "*.vb", SearchOption.AllDirectories)
    From l In File.ReadLines(f).Select(Function(x, i) New With { .Line = x, .LineNo = i + 1})
    Where l.Line.Contains(word2Search)
    Select FileName = f, LineNo = l.LineNo, Line = l.Line

匹配项将是 IEnumerable 个具有 FileNameLineNoLine 属性的对象。

更新

要获取文件名和匹配行索引的数组,您可以这样做:

Dim matches =
    From f In Directory.EnumerateFiles(startFolder, "*.vb", SearchOption.AllDirectories)
    From l In File.ReadLines(f).Select(Function(x, i) New With { .Line = x, .LineNo = i + 1})
    Where l.Line.Contains(word2Search)
    Select File = f, LineNo = l.LineNo
    Group By File Into g = Group
    Select FileName = File, LineNos = g.Select(Function(x) x.LineNo).ToArray()

这将为您提供 IEnumerable 个具有 FileNameLineNos 属性的对象。

找到匹配项在行中的位置需要更多更改,因为 Contains 只是 returns 一个 Boolean。您可以使用 Regex.Matches 查找行中匹配项的位置,因此:

Dim matches =
    From f In Directory.EnumerateFiles(startFolder, "*.vb", SearchOption.AllDirectories)
    From l In File.ReadLines(f).Select(Function(x, i) New With { .Line = x, .LineNo = i + 1})
    Where l.Line.Contains(word2Search)
    Select File = f, LineNo = l.LineNo,
        MatchPositions = Regex.Matches(l.Line, Regex.Escape(word2Search)).Cast(Of Match)().Select(Function(x) x.Index)
    Group By File Into g = Group
    Select FileName = File, Matched = g.Select(Function(x) New With { x.LineNo, .Positions = x.MatchPositions.ToArray() }).ToArray()

在此之后,您最终得到 IEnumerable 个具有 FileNameMatched 属性的对象(不幸的是,VB.NET 不喜欢被称为 Matches 因为它与 matches 变量冲突,但您可以根据自己的喜好使用它)。 Matched 属性 是具有 LineNoPositions 属性的对象数组,其中 Positions 是字符串索引的数组(从零开始,所以如果你愿意,可以在其中添加一个 + 1