查找并替换同时包含双引号和方括号的字符串



假设我有一个名为testfile.txt的测试文件,其中包含以下行:

one (two) "three"

我想使用PowerShell来说明,如果整个字符串存在,请在其正下方放置一行,其值为:

four (five) "six" 

(请注意,它包括空格、括号和双引号。这很重要,因为我遇到的问题是转义括号和双括号(。

所以结果是:

one (two) "three"
four (five) "six" 

我认为最简单的方法是,如果找到了第一个字符串,请再次将其替换为第一个字符串本身,新字符串组成包含在同一命令中的新行。我很难把字符串排成一行,所以我尝试使用herestring变量来读取整个带格式的文本块。它仍然不会将带引号的完整字符串解析到管道中。我是powershell的新手,所以如果你看到一些愚蠢的东西,不要退缩。

$herestring1 = @"
one (two) "three"
"@
$herestring2 = @"
one (two) "three"
four (five) "six"
"@
if((Get-Content testfile.txt) | select-string $herestring1) {
"Match found - replacing string"
(Get-Content testfile.txt) | ForEach-Object { $_ -replace $herestring1,$herestring2 } | Set-Content ./testfile.txt
"Replaced string successfully"
}
else {
"No match found"}

以上只是每次都给出"未找到匹配项"。这是因为它找不到文件中的第一个字符串。我尝试过使用backtick[`]和双引号的变体来尝试转义,但我认为here字符串的要点是它应该解析包括所有格式的文本块,这样我就不必这么做了。

如果我将文件更改为仅包含:

one two three

然后将herestring相应地更改为:

$herestring1 = @"
one two three
"@
$herestring2 = @"
one two three
four five six
"@

然后它工作正常,我得到字符串替换为我想要的。

正如Martin所指出的,可以将-SimpleMatchSelect-String一起使用,以避免将其解析为正则表达式。

-replace仍将使用正则表达式。

您可以使用[RegEx]::Escape():逃离RegEx的模式

$herestring1 = @"
one (two) "three"
"@
$herestring2 = @"
one (two) "three"
four (five) "six"
"@
$pattern1 = [RegEx]::Escape($herestring1)
if((Get-Content testfile.txt) | select-string $pattern1) {
"Match found - replacing string"
(Get-Content testfile.txt) | ForEach-Object { $_ -replace $pattern1,$herestring2 } | Set-Content ./testfile.txt
"Replaced string successfully"
}
else {
"No match found"}

正则表达式将括号()(您称之为括号(解释为特殊的。默认情况下,空格不是特别的,但可以使用某些regex选项。双引号没有问题。

在regex中,转义符是反斜杠,这与您使用backtick `为PowerShell解析器执行的任何转义无关。

[RegEx]::Escape()将确保正则表达式的任何特殊内容都被转义,以便正则表达式模式将其解释为文字,因此您的模式最终将如下所示:one (two) "three"

只需将Select-String cmdlet与-SimpleMatch开关一起使用即可:

# ....
if((Get-Content testfile.txt) | select-string -SimpleMatch $herestring1) {
# ....

-SimpleMatch

指示cmdlet使用简单匹配而不是常规匹配表达式匹配。在一个简单的匹配中,SelectString搜索输入用于Pattern参数中的文本。它不解释价值的正则表达式语句。

来源。

相关内容

  • 没有找到相关文章

最新更新