powershell 替换两行之间的文本

powershell replace text between 2 lines

我有一个文本文件,想替换两行之间的文本。这工作正常,直到两行之间没有文本。

我的代码:

$File = "D:\test.txt" 
$NewLine = "newline with some text"
$text = Get-Content "D:\test.txt" -raw

$text -replace ('(?m)(.*)^Line 3[\r\n]+Line 4([\r\n])', $NewLine) | 
  Out-File $File -Force

文本文件:

有效的文本文件:

Line 1
Line 2
Line 3
Line 4
Line 5
Line 6


文本文件不起作用:

Line 1
Line 2
Line 3
Some text here
Line 4
Line 5
Line 6

我做错了什么?

在此处更正了您的正则表达式以仅捕获第 3 行和第 4 行及其间的文本。

$File = 'D:\test.txt'
$NewLine = 'newline with some text'
$text = Get-Content -Path 'D:\test.txt' -Raw

$Pattern = '(?m)^Line\s3[\r\n]+.*?Line\s4'

$text -replace $Pattern,$NewLine | 
  Out-File -FilePath $File -Force

您遇到的问题是您的正则表达式(简称 RegEx)不允许第 3 行和第 4 行之间的任何内容。这是您正在使用的内容(稍微清理了一下):

(?m)^Line 3[\r\n]+Line 4[\r\n]

让我们稍微分解一下。 (?m) 将 RegEx 引擎置于多行模式,因此它允许您使用脱字符 ^ 来指示行的开头,而不仅仅是字符串的开头。它还有其他功能,但这就是您使用它的目的。我丢弃了 (.*),因为它毫无意义。所以你有一个 carat 表示一行的开头,然后是文本 Line 3,然后是 [\r\n]+,它将找到该行的结尾。然后它找到 Line 4,紧接着是该行的末尾。这就是为什么当有文本时它会失败,您不允许任何其他文本。为此,您可以使用 .*?。这意味着:点表示任何字符,无论是字母、数字、符号,甚至是未在屏幕上注册的字符。星号 * 表示需要零个或多个,因此任何字符都需要零个或多个。问号告诉它寻找零个或多个,但在继续模式之前匹配尽可能少的字符,因此它只会匹配直到它可以移动到 Line 4[\r\n] 的东西。功能模式将是:

(?m)^Line 3[\r\n]+.*?[\r\n]Line 4[\r\n]