首页 > 解决方案 > 使用正则表达式选择字符串并拆分/输出到多个文件

问题描述

今天是个好日子

想就我在选择字符串/正则表达式上做错了什么寻求建议。当 '(?m)(abc)(.*?)(--- End ---)'在 Notepad++ 上测试模式为

如果我将正则表达式更改为'(?m)(abc)(.*?)',它将获取从 Line1 到 Line12 的全部内容。

我想捕获并能够将结果拆分为 3 个结果文件 File1 - (内容从 Line1 到 Line4) File2 - (内容 Line5 到 Line8) File3 - (内容 Line9 到 Line12

Broken Command that i used:
While (line is not equal to end of file) {
Get-ChildItem "C:\Users\ASUS\Desktop\Pscript\test-script.txt" | ForEach {
$getctnt = Get-Content $_.FullName
$getctnt | Select-String -Pattern '(?m)(abc)(.*?)(--- End ---)' | Out-File .\result$a.txt
$a++
}
}

Content of the Test-script.txt:
Line1       abc
Line2       content1
Line3       conten2
Line4       --- End ---
Line5       abc
Line6       content1
Line7       content2
Line8       --- End ---
Line9       abc
Line10      content1
Line11      content2
Line12      --- End ---

标签: regexpowershellwhile-loopselect-string

解决方案


您尝试的问题源于阅读不Test-script.txt正确。当您在Get-Content不带-Raw开关的情况下运行命令时,文件将作为字符串数组读入。当它被输入时Select-String,该命令一次只会处理一行,并且对前一行或下一行一无所知。如果您实现该-Raw开关,它将在文件中读取为一个字符串。然后你可以输入Select-String并能够匹配换行符。话虽如此,您将需要启用单行修饰符 ( ?s).以匹配\n\r字符。由于同一个正则表达式模式有多个匹配项,因此您需要添加-AllMatches开关。

$getctnt = Get-Content $_.FullName -Raw
$selections = $getctnt | Select-String -Pattern '(?s)(abc)(.*?)(--- End ---)' -AllMatches

$selections现在将包含一个对象数组MatchInfo,您可以根据需要对其进行迭代或索引。以下是访问这些值的方式。

$selections.Matches # For the MatchInfo objects
$selections.Matches.Value # For the matched values

由于您使用了多个括号集,因此您创建了 4 个捕获组 (0,1,2,3) 和三个总匹配项。我不知道这是否是您的意图,但它们也可以访问。要轻松访问它们,您可以遍历 3 个MatchInfo对象(总共三个匹配项)。

$selections.Matches | Foreach-Object {
    $_.Groups[0] # Each full regex match
    $_.Groups[1] # Capture group 1: (abc)
    $_.Groups[2] # Capture group 2: (.*?)
    $_.Groups[3] # Capture group 3: (--- End ---)
}

推荐阅读