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

就像其他許多語言一樣,PowerShell可以處理字符串和文本。其中一個有用的功能是使用PowerShell替換文件中的字符、字符串甚至文本。

在本教程中,您將學習如何使用PowerShell的replace()方法和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 命令方法,如下所示。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 替換運算符

雖然使用 PowerShell 替換字符串方法是替換文本的最簡單方法,但您也可以使用 PowerShell 的replace運算符。該replace運算符與方法類似,您提供要查找和替換的字符串。但是,它有一個重大優勢;能夠使用正則表達式(regex)來查找匹配的字符串(稍後詳述)。

使用上述示例,您可以使用replace運算符以類似的方式將hello替換為hi。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 Regex Replace

如上所述,使用 PowerShell replace 方法替換字符串是有效的,但受限制。您僅能使用文字字符串。您無法使用萬用字符或正則表達式。如果進行任何中級或高級替換,您應該使用 replace 運算符。

假設您有一個包含使用變量創建的字符串的腳本。該字符串應該是 hello, worldhi, world. 也許您作為系統管理員度過了糟糕的一天,想要無論值是什麼,都將字符串更改為 goodbye, world

您需要將 hello, worldhi, world 都轉換為 goodbye, world。為實現此目的,您需要使用正則表達式。您可以使用正則表達式匹配文本中的幾乎任何特定模式。

在此示例中,您可以使用表達式 hello|hi 來匹配所需的兩個字符串,使用正則表達式 “or”(|)字符 如下所示。

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()方法,但如果您需要匹配和替换更高级的内容,请始终使用replace运算符。

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