【问题标题】:Multiline regex match in PowerShellPowerShell 中的多行正则表达式匹配
【发布时间】:2015-06-10 15:04:25
【问题描述】:

我正在尝试从文本文件中提取特定的行块,其中包含如下内容:

...
sCountry = "USA"
sCity = "New York"
sState = "New York"
...
sCountry = "USA"
sCity = "Los Angeles"
sState = "California"

这三行在整个文本文件中重复;我只想提取那些文本行,并将数据字段放入 csv 中,这样我就有了类似

"USA","New York","New York"
"USA","Los Angeles","California"
...

到目前为止,我有这个:

$inputPath = 'C:\folder\file.vbs'
$outputFile = 'C:\folder\extracted_data.csv'
$fileContent = [io.file]::ReadAllText($inputPath)

$regex = '(?sm)(s[A-Z][a-z]+ = "\w*"(\s*$)){3}'

$fileContent = $fileContent | Select-String $regex -AllMatches | % {$_.Matches} | % {$_.Value}
$fileContent = [regex]::Replace($fileContent, 'sCountry = ', '')
$fileContent = [regex]::Replace($fileContent, '(?sm)((^\s*)s[A-Z][a-z]+ = )', ',')
$fileContent > $outputFile

通过查看这个我能够获得:

Multiline regex to match config block.

但是,当我运行脚本时,我的输出文件是空的。它不会与我提供的 $regex 模式进行模式匹配,但如果我执行以下操作,它将在一行上匹配:

$regex = '(?sm)(sCountry = "\w*"(\s*$))'

但如果我做类似的事情就不会:

$regex = '(?sm)(s[A-Z][a-z]+ = "\w*"(\s*$))'

如何使模式匹配跨多行工作?

【问题讨论】:

  • 你用的是什么版本的powershell?
  • @mjolinor,Windows PowerShell ISE,3.0,非 (x86)

标签: regex powershell


【解决方案1】:

完全使用您在帖子中的测试数据,我使用Select-StringConvertFrom-StringData 采取了不同的方法。这有一个小缺陷,可能会被忽略(如果你真的需要,也可以解决)。这里需要注意的是,sCountry 行必须首先出现,sState 行必须在组中最后出现。

$results = ((Get-Content C:\temp\test.txt -Raw) | 
    Select-String -Pattern "(?sm)sCountry.*?sState.*?$" -AllMatches).Matches.Value
$results | ForEach-Object{
    New-Object -TypeName PSCustomObject -Property ($_.Replace('"','') | ConvertFrom-StringData)
} | Export-CSV -NoTypeInformation C:\temp\output.csv

为了获取数据组,这里的正则表达式将抓取从“sCountry”到下一个“sState”所在行的末尾的所有内容。如果除了预期的线之外还有其他线,则当前的逻辑将失败。我们用简单的.Replace('"','') 去掉了变量引号。我认为这是次要的,但生成的标题有前导 s,这可能没什么大不了的。

PowerShell 中的对象在导出为 CSV 之前如下所示

sCity       sCountry sState    
-----       -------- ------    
New York    USA      New York  
Los Angeles USA      California

这将在 csv 中像这样净输出

"sCity","sCountry","sState"
"New York","USA","New York"
"Los Angeles","USA","California"

很酷的想法是您不能在导出数据之前对其进行排序。或者你可以用 PowerShell 对象做的任何事情。

【讨论】:

    猜你喜欢
    • 2014-09-10
    • 2021-12-07
    • 2011-08-18
    • 2017-07-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-11
    相关资源
    最近更新 更多