Powershell 多行正则表达式块

powershell multiline regex block

我真的对尝试使用多行正则表达式感到沮丧,我对 Powershell 的经验很少,虽然我尝试过的示例有效,但一旦我开始调整它们以适应什么我需要它永远不会给出任何结果。

下面是我的文本文件示例

CLO*5000000Z115240057*598.50***94>0
DGP*115*G8*20161024~
DGP*096*G8*20161024~
DI*ABC>121~
QM1*BN*1*~
QM2*H2*1*~
QM1397*2*~
Q3*~
Q4*~
TX*1~
SQU*HV>01480>AB>1S>1>2>3>4~
0T1*472*D8*20160915~
RBF*6R*374196~
TX*2~

同一个文本文件中可能有 200 个(最多)这些。我正在搜索以 'SQU' 开头以在末尾包含 1>2>3>4 的行,只有少数行。我能够使用下面找到的代码示例找到所有 SQU 行,不幸的是,我还需要获取它上面的 'CLO' 行。

$fpath = 'C:\myfile.txt'
$opath = 'C:\logoutput.txt'
$regx = 'SQU.*1>2>3>4.*'
Get-Content $fpath | % { if($_ -match $regx) {add-content $opath $_}}

我已经尝试过,而且我已经在下面的示例中以我能想到的每种组合尝试了数十个 $、^ 和 ()。我也不太明白如何将它放入 logoutput.txt。

$fileContent = [io.file]::ReadAllText($fpath)
$filecontent | Select-String '(?ms)CLO.*SQU.*1>2>3>4.*' -AllMatches | %{ $_.Matches } | %{ $_.Value } 

我在没有 >1>2>3>4 的情况下尝试了这个,只是想看看我是否能得到任何东西,但没有运气。

$stringmatch = Get-Content -raw $fpath
if (Select-String -inputobject $stringmatch -pattern '(?smi)CLO.*SQU.*'){
$matches[1]
} 

我只需要 CLO 和 SQU 行(如果它有 1>2>3>4),但老实说,如果更容易的话,我会选择整个块。 任何帮助将不胜感激。

在您的第二个示例中 - 您读取文本文件,然后匹配正则表达式,然后打印出值。该值将显示匹配的全部内容,其中包括 CLO 和 SQU 之间的所有 .*。而是在您关心的行上使用组捕获(使用括号),然后仅打印组的值。

另外 - 修改了正则表达式以使用非贪婪匹配,以便多个匹配可以正常工作。 对正则表达式的另一个修改是您不想匹配 CLO 和 SQU 组中行尾之后的字符 - 因此请确保这些匹配以行尾指示符 $ 结束。

$fileContent = [io.file]::ReadAllText($fpath)
$filecontent | Select-String '(?ms)(CLO[^\n]*?$).*?(SQU.*?1>2>3>4[^\n]*$)' -AllMatches | %{ $_.Matches } | %{ $_.Groups[1].Value; $_.Groups[2].Value }
$fileContent = [io.file]::ReadAllText($fpath)

# Match lines beginning with CLO, and lines beginning with SQU
$m = [regex]::Matches($fileContent,
                      '(?<clo>^CLO.*?$).*?(?<squ>^SQU.*?$)',
                      [System.Text.RegularExpressions.RegexOptions]('Multiline', 'Singleline')) 

# Filter out only the pairs where the SQU lines also have the right ending
$m | Where-Object { $_.Groups['squ'].Value -match "1>2>3>4~" } | 
     ForEach-Object { 
        $_.Groups['clo'].Value
        $_.Groups['squ'].Value
}