2015-10-22 3 views
2

Привет всем, я нашел следующий код HERE и задавался вопросом, возможно ли, если я могу получить номер строки, где слово появляется с помощью запроса LINQ или каким-либо другим способом?Поиск слова и поиск номера строки 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 

код работает для поиска слово, но мне бы очень хотелось, чтобы иметь возможность знать, какую линию он был найден, а также.

Любая помощь будет замечательной!

+0

Что делать, если этот термин появляется несколько раз в файле? –

+0

@FarhanAnam, тогда я хотел бы, чтобы он дал мне знать, какие строки находятся внутри этого документа. ** (пример: строки 15, 22, 108) ** – StealthRT

ответ

2

Метод LINQ Selecthas 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 объектов с FileName, LineNo и Line свойствами.

UPDATE

Чтобы получить имя файла и массив индексов соответствия строки, вы могли бы сделать что-то вроде этого:

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 объектов с FileName и LineNos Недвижимость.

Для поиска позиций спичек в строках требуется еще несколько изменений, так как Contains просто возвращает 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 объектов с FileName и Matched свойствами (к сожалению, VB.NET не понравилось, что называемый Matches, потому что это противоречит переменной matches, но вы можете поиграть с ней по своему вкусу). Свойство Matched представляет собой массив объектов с объектами LineNo и Positions, причем Positions является массивом индексов в строках (на основе нуля, поэтому добавьте + 1 туда, если хотите).

+0

Ваш комментарий к вопросу уточняет, что вы ищете, поэтому я думаю, что это немного не работает. Я обновляю через минуту, чтобы показать, просто вернув имя файла и соответствующие номера строк. – Mark

+0

Спасибо за код, но я не верну никаких результатов, используя ваш код? – StealthRT

+0

@StealthRT Вы взяли редактирование, которое я сделал, чтобы исправить поисковый запрос? Он был жестко закодирован в первой версии для соответствия моим тестовым данным. Извини за это. – Mark

Смежные вопросы