Сопоставление повторяющихся подсерий с использованием регулярного выражения с PowerShell - PullRequest
1 голос
/ 18 мая 2010

У меня есть текстовый файл, в котором перечислены имена большого количества электронных таблиц Excel и имена файлов, на которые есть ссылки из электронных таблиц.

В упрощенном виде это выглядит так:

"Parent
 File1.xls"

  Link: ChildFileA.xls
  Link: ChildFileB.xls
"ParentFile2.xls"
"ParentFile3.xls"
  Blah
  Link: ChildFileC.xls
  Link: ChildFileD.xls
  More Junk
  Link: ChildFileE.xls
"Parent
 File4.xls"
  Link: ChildFileF.xls

В этом примере ParentFile1.xls имеет встроенные ссылки на ChildFileA.xls и ChildFileB.xls, ParentFile2.xls не имеет встроенных ссылок, а ParentFile3.xls имеет 3 встроенных ссылки.

Я пытаюсь написать регулярное выражение в PowerShell, которое будет анализировать текстовый файл с выводом в следующем виде:

ParentFile1.xls:ChildFileA.xls,ChildFileB.xls
ParentFile3.xls:ChildFileC.xls,ChildFileD.xls,ChildFileE.xls
etc

Задача усложняется тем фактом, что текстовый файл содержит много мусора между каждой строкой, и у родителя не всегда может быть дочерний элемент. Кроме того, одно имя файла может проходить через несколько строк. Однако это не так плохо, как кажется, поскольку имена родительских и дочерних файлов всегда четко разграничены (родительский с кавычками и дочерний с префиксом Link:).

Код PowerShell, который я использовал, выглядит следующим образом:

$content = [string]::Join([environment]::NewLine, (Get-Content C:\Temp\text.txt))
$regex = [regex]'(?im)\s*\"(.*)\r?\n?\s*(.*)\"[\s\S]*?Link: (.*)\r?\n?'
$regex.Matches($content) | %{$_.Groups[1].Value + $_.Groups[2].Value + ":" + $_.Groups[3].Value}

Используя приведенный выше пример, он выводит:

ParentFile1.xls:ChildFileA.xls
ParentFile2.xls""ParentFile3.xls:ChildFileC.xls
ParentFile4.xls:ChildFileF.xls

Есть две проблемы. Во-первых, включение "" вместо новой строки при обработке родительского элемента без дочернего элемента. И вторая проблема, которая является наиболее важной, заключается в том, что для каждого родителя отображается только один ребенок. Я предполагаю, что мне нужно каким-то образом рекурсивно захватывать и отображать множественные дочерние ссылки, которые существуют для каждого родителя, но я полностью озадачен тем, как сделать это с помощью регулярного выражения.

Помощь Эми будет принята с благодарностью. Файл содержит сотни тысяч строк, и ручная обработка невозможна:)

1 Ответ

1 голос
/ 18 мая 2010

Лично я бы решил только часть этого с помощью регулярных выражений.

Сначала я бы присоединился к именам родительских файлов, например:

$text = (Get-Content C:\Temp\text.txt) -join "`r`n"
$text = [regex]::replace($text, '(?im)"Parent[^"]+"', { [regex]::replace($args, '(?m)\s*', '')  } )

А затем продолжить ручную обработку.

$res = @()
$parent = $null
switch -regex ($text -split "`n") {
    '^"Parent' { if ($parent) { $res += $parent }
                 $parent = new-object PsObject -prop @{Name = $_.Trim('"'); Links=@()}
    }
    '^\s*Link:' { $parent.Links += $_ -replace '^\s*Link:\s*', '' }
}
if ($parent) { $res += $parent }

$res | % { 
 $n = $_.Name
 $links = $_.Links -join ','
 write-host "$n`:$links"
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...