使用PowerShell使用正则表达式匹配重复子系列

时间:2010-05-18 10:18:15

标签: regex powershell

我有一个文本文件,列出了大量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

有两个问题。首先,每当处理没有孩子的父母时,包含“”而不是换行符。第二个问题,也是最重要的问题,就是每个父母只会展示一个孩子。我猜我需要以某种方式递归地捕获并显示每个父节点存在的多个子链接,但我完全不知道如何使用正则表达式执行此操作。

艾米的帮助将不胜感激。该文件包含100个数千行,并且不能选择手动处理:)

1 个答案:

答案 0 :(得分:1)

就个人而言,我只会使用正则表达式来解决其中的一部分。

首先,我会加入像这样的父文件名:

$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"
}