如何使用 PowerShell Replace 替换文本 [示例]

与许多其他语言一样,PowerShell 可以处理字符串和文本。其中一个有用的功能是使用 PowerShell 替换文件中的字符、字符串甚至文本。

在本教程中,您将学习如何使用 PowerShell 的 replace() 方法和 PowerShell 的 replace 运算符。本教程将涵盖基础知识,甚至深入探讨一些“有趣”的正则表达式!

开始之前

您不需要太多东西来跟随本教程中的所有示例;您只需要 PowerShell。本教程示例将使用 PowerShell v7.0.2,但所有示例应该在 Windows PowerShell 中工作。

使用 PowerShell 替换字符串:基础知识

使用 PowerShell 替换的最简单情况之一是替换字符串中的字符。让我们从一些示例开始。

假设您在 PowerShell 中有一个字符串,其值为 hello, world

$string = 'hello, world'

您想要将该字符串中的 hello 字符串替换为 hi 字符串,使得 $string 变量具有值 hi, world。为此,PowerShell 首先需要找出“查找”文本所在的位置。一旦找到,然后将该文本替换为用户定义的值。

使用Replace()方法

替换字符串的一种最简单的方法是使用 PowerShell 的替换命令方法,如下所示。 replace()方法有两个参数;要查找的字符串和要用找到的文本替换的字符串。

如下所示,PowerShell正在查找字符串hello并将该字符串替换为字符串hi。然后该方法返回最终结果,即hi, world

PS> $string.replace('hello','hi')
hi, world

您可以调用 PowerShell 的替换方法来替换任何字面字符串。如果未找到要替换的字符串,则replace()方法将返回空。

您不需要将字符串分配给变量以替换字符串中的文本。相反,您可以直接在字符串上调用replace()方法,如:'hello world'.replace('hello','hi')。本教程为了方便使用了一个变量。

删除字符

也许您想从另一个字符串中删除字符串中的字符,而不是用其他内容替换它。您也可以通过指定空字符串来做到这一点。

PS> $string.replace('hello','')
, world

替换多个实例

现在您已经有了在另一个字符串中替换字符串的代码。那么替换多个字符串呢?没问题。

由于 PowerShell 替换方法返回一个字符串,要替换另一个实例,您可以在末尾附加另一个replace()方法调用。然后 PowerShell 在原始输出上调用replace()方法。

PS> $string.replace('hello','').replace('world','earth')
, earth

您可以根据需要链式调用多个replace()方法,但如果有许多字符串需要替换,您应该考虑使用replace运算符。

使用 PowerShell Replace 运算符

虽然使用 PowerShell 替换字符串方法是替换文本的最简单方法,但您也可以使用 PowerShell replace运算符。replace运算符类似于方法,您提供要查找和替换的字符串。但是,它有一个很大的优势;即能够使用正则表达式(regex)查找匹配的字符串(稍后详细介绍)。

使用上述示例,您可以使用replace运算符以类似的方式替换hellohi。PowerShell 执行相同的步骤。

PS> $string -replace 'hello','hi'
hi, world

删除字符

与 PowerShell 替换方法类似,您也可以使用replace运算符从字符串中删除字符。但是,与replace()方法不同,您还可以完全将字符串排除为替换参数,您会发现效果相同。

PS> $string -replace 'hello',''
, world
PS> $string -replace 'hello'
, world

替换多个实例

replace()方法类似,您还可以链式使用replace运算符。由于replace运算符返回字符串,如下所示。在下一节中,您将看到使用正则表达式的代码将更清晰。

PS> $string -replace 'hello','hi' -replace 'world','earth'
hi, earth

使用 PowerShell 正则表达式替换

如上所述,PowerShell 替换方法中的字符串替换是有效的,但受限制。您只能使用文字字符串。您不能使用通配符或正则表达式。如果要执行任何中间或高级替换,应该使用replace运算符。

假设您有一个包含变量创建的字符串的脚本。该字符串应为hello, worldhi, world.也许您作为系统管理员度过了糟糕的一天,想要更改字符串,而不管其值如何,变为goodbye, world

您需要将hello, worldhi, world都转换为goodbye, world。为实现此目的,您需要使用正则表达式。您可以使用正则表达式匹配文本中的几乎任何特定模式。

在此示例中,您可以使用表达式hello|hi,使用正则表达式“或” (|) 字符,如下所示,匹配两个所需字符串。

PS> 'hello, world' -replace 'hello|hi','goodbye'
goodbye, world
PS> 'hi, world' -replace 'hello|hi','goodbye'   
goodbye, world

一旦学会使用正则表达式查找字符串,您就可以使用 PowerShell 替换匹配任何模式的通配符字符串。

转义正则表达式字符

在上面的正则表达式示例中,要搜索的字符串中不包含任何正则表达式特殊字符。正则表达式语言有一些特殊字符,它们不像大多数字母和数字一样被字面解释。

例如,也许你需要替换字符串中的文本。该字符串包含了一些正则表达式的特殊字符,如括号和问号。然后,你尝试将字符串[hello]替换为goodbye,如下所示。

PS> '[hello], world' -replace '[hello]','goodbye'
[goodbyegoodbyegoodbyegoodbyegoodbye], wgoodbyergoodbyed

这显然不是你的本意。当你在字符串中使用正则表达式特殊字符进行查找时([hello]),就会出现这种情况。

为了避免这个问题,你有两个选择。你可以通过在每个字符前面加上反斜杠来转义这些特殊字符,或者使用Escape()方法

下面你可以看到使用反斜杠转义每个特殊字符的效果。

PS> '[hello], world' -replace '\[hello\]','goodbye'
goodbye, world

作为另一种选择,也是推荐的选择,你可以使用正则表达式类型的Escape()方法自动删除所有特殊字符。

PS> '[hello], world' -replace ([regex]::Escape('[hello]')),'goodbye'
goodbye, world

在可能的情况下,你应该使用Escape()方法,因为它会转义所有特殊字符,这样你就不必记住它们。

使用匹配/捕获组

在所有之前的示例中,本教程一直在使用字面字符串来替换另一个字符串。 您一直在使用higoodbye。 但是,如果您想要使用 PowerShell 在字符串中找到的一个或多个字符来替换呢? 您需要匹配或捕获组

正则表达式有一个称为捕获组和反向引用的概念。 捕获组允许您捕获字符串,然后在其他地方引用它们。 PowerShell 通过使用replace运算符与匹配组来利用此功能。

例如,也许您有一个可能包含几个不同值的字符串。

'hello world, you sexy beast'
'hi world, now go away'
'hello earth, you are lovely today'

您想要交换字符串的第一部分和第二部分,使它们看起来像这样:

'you sexy beast,hello world'
'now go away,hi world'
'you are lovely today,hello earth'

要执行此操作,PowerShell 必须找到逗号左右的所有文本。 一旦知道了那个文本是什么,它就必须用另一个替换它。 为此,您需要反向引用。

A backreference is a regex variable (not a PowerShell variable) that represents the text that regex matched. Backreferences in PowerShell are represented with a dollar sign followed by a number indicating the order in which they were matched.

您可以看到下面的一个示例。

## 此字符串也可以是:
## 'hi, world, now go away'
## 'hello, earth, you are lovely today'
PS> $string = 'hello, world, you sexy beast'
PS> $string -replace '(.*), (.*)','$2,$1'
you sexy beast,hello world

在上面的例子中,你可以看到正则表达式捕获组用括号括起每个匹配项(hello world)和(you sexy beast)。然后,对于替换,从左到右首先匹配了hello word,因此它得到一个$1的反向引用标签,you sexy beast得到$2的反向引用标签。

一旦PowerShell知道每个匹配的值,你可以在替换文本中以任何你喜欢的方式使用这些引用。在这个例子中,$2,$1交换了它们的位置。

使用命名匹配组

如果你不想使用类似$1$2这样的数字占位符来引用匹配值,你也可以使用标签或名称。你不必从左到右数哪个引用表示什么,只需使用名称即可。

要使用名称作为引用,你需要首先在匹配字符串中为每个匹配定义标签。为此,你必须定义捕获组,如(?<label><regex>),其中label是名称,<regex>是你正在使用的正则表达式。

一旦你定义了名称,你就可以在替换字符串中使用美元符号并用花括号括起名称,例如${label}

你可以在下面看到这种技术的演示。

PS> $string = 'hello, world, you sexy beast'
PS> $string -replace '(?<First_Part>.*), (?<Second_Part>.*)','${Second_Part},${First_Part}'
you sexy beast,hello, world

结论

当你学到了,PowerShell替换运算符允许你以许多不同的方式替换字符、文本和字符串。要执行简单的替换,你可以使用replace()方法,但如果你需要匹配和替换更复杂的内容,始终使用replace运算符。

Source:
https://adamtheautomator.com/powershell-replace/