regex - 使用正则表达式选择字符串并拆分/输出到多个文件
问题描述
今天是个好日子
想就我在选择字符串/正则表达式上做错了什么寻求建议。当 '(?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 ---
解决方案
您尝试的问题源于阅读不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 ---)
}