2016-08-28 1 views
1

Я хочу найти некоторые шаблоны регулярных выражений в файлах (* .txt), которые находятся внутри папки, путь которой я указал в текстовом поле, и папка содержит другие подпапки с txt-файлами в форме 12345 \ 2031 \ 30201 \ txt \ 120.txt, и если шаблон совпадает даже в одном файле, строка записывается в файл журнала, который создается внутри папки, путь которой я указывал в текстовом поле, а затем она переходит к следующему регулярное выражение и так далее Что я сделал до сих пор являетсяКак сопоставить несколько шаблонов регулярных выражений в нескольких файлах и записать что-то в файл журнала?

Dim tLoc As String = TextBox1.Text 
     Dim txtFilesArray = Directory.EnumerateFiles(tLoc, "*.txt", SearchOption.AllDirectories).Where(Function(f) f Like "*\#*\#*\#*\txt\#*.txt") 
     Dim fileLoc As String = tLoc & "\Checklist.log" 
     Dim fs As FileStream = Nothing 
     If (Not File.Exists(fileLoc)) Then 
      fs = File.Create(fileLoc) 
      Using fs 

      End Using 
     End If 
     For Each tFile In txtFilesArray 
      Dim input As String = File.ReadAllText(tFile) 
      Dim pattern1 As New Regex("(?<!>)(figure|fig\.|figs\.|figures) (\d+)") 
      Dim pattern2 As New Regex("(?<!>)(table|tab\.|tabs\.|tables) (\d+)") 
      If pattern1.IsMatch(input) Then 
       FileOpen(1, fileLoc, OpenMode.Append) 
       PrintLine(1, "Check figure link") 
       FileClose() 
      End If 
      If pattern2.IsMatch(input) Then 
       FileOpen(1, fileLoc, OpenMode.Append) 
       PrintLine(1, "Check table link") 
       FileClose() 
      End If 

     Next 

Но проблемы: 1) Даже если pattern1 матчей в нескольких файлах, я хочу, чтобы написать строку Проверить фигурную ссылку только один раз в файле журнала и не каждый раз, когда он находит совпадение в разных файлах и тот же для pattern2 .... patternN, более того, я хочу, чтобы программа переходила к следующему шаблону регулярного выражения, совпадающему с моментом совпадения pattern1 в одном файле (нет необходимости искать тот же шаблон в других файлах) 2) У меня есть около сотни шаблонов регулярных выражений, которые я хочу использовать в этой программе, может ли кто-нибудь сказать мне, как мне сократить кодировку?

+0

Звучит как вещь программирования, а не вещь регулярного выражения. Я думаю, вы можете удалить тег 'regex'. – Whothehellisthat

ответ

1

Вы можете поместить образцы в какой-то коллекции, а затем удалить их из нее, когда нашли

Dim re = Function(p$) New Regex(p, RegexOptions.Compiled) 
Dim patterns = New Dictionary(Of String, Regex) From { 
    {"Check figure link", re("(?<!>)(figure|fig\.|figs\.|figures) (\d+)")}, 
    {"Check table link", re("(?<!>)(table|tab\.|tabs\.|tables) (\d+)")} 
} 
Dim output = New List(Of String) 
Dim tLoc = TextBox1.Text 
Dim txtFiles = Directory.EnumerateFiles(tLoc, "*.txt", SearchOption.AllDirectories) 

For Each tFile In txtFiles 
    If Not tFile Like "*\#*\#*\#*\txt\#*.txt" Then Continue For 
    Dim input = File.ReadAllText(tFile) 

    Dim match = "" 
    For Each pattern In patterns 
     If pattern.Value.IsMatch(input) Then 
      match = pattern.Key 
      Exit For 
     End If 
    Next 
    If match > "" Then 
     output.Add(match) 
     patterns.Remove(match) 
    End If 
Next 
File.WriteAllLines(tLoc.TrimEnd("\"c) & "\Checklist.log", output) 

Если вы хотите сравнить каждый шаблон со всеми файлами, то это будет проще распараллелить (бег на несколько процессоров, в то же время), потому что не будет никакой необходимости, чтобы удалить их из коллекции:

Dim patterns = New List(Of String()) From { 
    ({"Check figure link", "(?<!>)(figure|fig\.|figs\.|figures) (\d+)"}), 
    ({"Check table link", "(?<!>)(table|tab\.|tabs\.|tables) (\d+)"})} 

Parallel.ForEach(patterns, 
    Sub(pattern) 
     Dim tLoc = TextBox1.Text 
     Dim output = New List(Of String) 
     Dim txtFiles = Directory.EnumerateFiles(tLoc, "*.txt", SearchOption.AllDirectories) 
     Dim regEx = New Regex(pattern(1), RegexOptions.Compiled) 

     For Each tFile In txtFiles 
      If tFile Like "*\#*\#*\#*\txt\#*.txt" Then 
       Dim input = File.ReadAllText(tFile) 
       If regEx.IsMatch(input) Then 
        output.Add(pattern(0)) 
        Exit For 
       End If 
      End If 
     Next 
     File.AppendAllLines(TextBox1.Text.TrimEnd("\"c) & "\Checklist.log", output) 
    End Sub) 

или этой короткой более сложной версии

Dim patterns = New List(Of String()) From { 
    ({"Check figure link", "(?<!>)(figure|fig\.|figs\.|figures) (\d+)"}), 
    ({"Check table link", "(?<!>)(table|tab\.|tabs\.|tables) (\d+)"})} 

Dim output = From pattern In patterns.AsParallel 
      Let regEx = New Regex(pattern(1), RegexOptions.Compiled) 
      From tFile In Directory.EnumerateFiles(TextBox1.Text, "*.txt", SearchOption.AllDirectories) 
      Where tFile Like "*\#*\#*\#*\txt\#*.txt" AndAlso regEx.IsMatch(File.ReadAllText(tFile)) 
      Take 1 
      Select pattern(0) 

File.WriteAllLines(TextBox1.Text.TrimEnd("\"c) & "\Checklist.log", output) 
+0

Первая кодировка показывает исключение «Исключение выбрано:« System.InvalidOperationException »в mscorlib.dll' –

+0

@Don_B. О, я думаю, проблема в том, что я удаляю внутри цикла. Я обновлю пример позже – Slai

+0

Не могли бы вы объяснить свой код «более короткой более сложной версии», как он работает? Я полностью потерял его ... Thnx заранее. –

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