多くの他の言語と同様に、PowerShellは文字列とテキストを扱うことができます。その中でも便利な機能の一つは、PowerShellを使用してファイル内の文字、文字列、さらにはテキストを置換することです。
このチュートリアルでは、PowerShellのreplace()
メソッドとPowerShellのreplace
演算子の使い方について学びます。このチュートリアルでは基本的な内容から、いくつかの「楽しい」正規表現までカバーします!
始める前に
このチュートリアルのすべての例に従うためには、PowerShellが必要です。このチュートリアルの例ではPowerShell v7.0.2を使用していますが、すべての例はWindows PowerShellでも動作するはずです。
PowerShellを使って文字列を置換する:基本
PowerShellを使用して文字列内の文字を置換する場合は、最も単純なケースの一つです。いくつかの例から始めましょう。
PowerShellで値がhello, world
という文字列があるとします。
その文字列内のhello
という文字列をhi
という文字列で置換して、$string
変数の値をhi, world
にしたいとします。これを実現するために、PowerShellはまず「検索」テキストの場所を見つける必要があります。見つけた後、ユーザーが指定した値でそのテキストを置換します。
Replace()
メソッドの使用方法
PowerShellのreplaceコマンドメソッドを使用して、文字列を置換する最も簡単な方法の一つは、以下に示すようにreplace()
メソッドを使用することです。replace()
メソッドには2つの引数があります。検索する文字列と、見つかったテキストを置換する文字列です。
以下の例では、PowerShellが文字列hello
を検索し、その文字列を文字列hi
で置換しています。メソッドは最終結果としてhi, world
を返します。
任意の文字列に対してPowerShellのreplaceメソッドを呼び出すことで、任意のリテラル文字列を別の文字列で置換することができます。文字列が見つからない場合、replace()
メソッドは何も返しません。
文字列内のテキストを置換するために、変数に文字列を割り当てる必要はありません。代わりに、
'hello world'.replace('hello','hi')
のように文字列自体でreplace()
メソッドを直接呼び出すことができます。このチュートリアルでは、便宜上変数を使用しています。
文字の削除
文字列内の文字を別の文字列で置換するのではなく、削除したい場合もあります。その場合は、空の文字列を指定することもできます。
複数のインスタンスの置換
他の文字列内の文字列を置換するコードを持っていますが、複数の文字列を置換する場合はどうすればよいでしょうか?それも問題ありません。
PowerShellのreplaceメソッドは文字列を返すため、別のインスタンスを置換するためには、元の出力にreplace()
メソッドの呼び出しを追加することができます。PowerShellはその後、元の出力に対してreplace()
メソッドを呼び出します。
必要なだけ
replace()
メソッド呼び出しを連鎖させることができますが、多くの文字列を置換する場合はreplace
演算子を使用することを検討する必要があります。
PowerShellのReplace演算子の使用
テキストを置換するためには、PowerShellの置換文字列メソッドを使用する方法が最も簡単ですが、PowerShellのreplace
演算子も使用できます。このreplace
演算子は、置換すべき文字列を指定する点でメソッドと似ています。しかし、大きな利点があります。それは、正規表現(regex)を使用して一致する文字列を検索できるという点です(後述)。
上記の例を使って、以下のようにreplace
演算子を使用してhello
をhi
に置換することができます。PowerShellは同じ手順を実行します。
文字の削除
PowerShellのreplace
演算子を使用して、文字列から文字を削除することもできます。ただし、replace()
メソッドとは異なり、置換する文字列を引数に完全に除外することもできます。この場合も同じ効果が得られます。
複数のインスタンスの置換
replace()
メソッドと同様に、replace
演算子を連鎖させることもできます。replace
演算子は以下のように文字列を返すため、次のセクションでは正規表現を使用することでコードがよりスマートになります。
PowerShellのRegex Replaceを使用する
上記のように、PowerShellのreplaceメソッドを使用して文字列を置換することはできますが、制限があります。リテラル文字列のみ使用できます。ワイルドカードや正規表現は使用できません。中級または高度な置換を行う場合は、replace
演算子を使用する必要があります。
スクリプトに変数で作成された文字列が含まれているとします。その文字列はhello, world
またはhi, world.
のいずれかである必要があります。システム管理者として悪い日を過ごしたかもしれませんが、値に関係なく文字列をgoodbye, world
に変更したい場合は、次のようにします。
hello, world
とhi, world
の両方をgoodbye, world
に変換する必要があります。これを実現するには、正規表現を使用する必要があります。正規表現を使用してテキスト内の特定のパターンをほぼすべてマッチさせることができます。
この例では、正規表現「または」(|
)文字を使用して、下記のように必要な両方の文字列に一致させることができます。
文字列を見つけるために正規表現を使い方を学ぶと、ワイルドカード文字列を一致させるためにPowerShellを使用することができます。任意のパターンに一致するワイルドカード文字列を置換することができます。
正規表現文字のエスケープ
上記の正規表現の例では、検索対象の文字列には正規表現の特殊文字は含まれていませんでした。正規表現言語には、一般の文字や数字とは異なる意味で解釈される特定の文字があります。
例えば、文字列内のテキストを置換する必要があるかもしれません。その文字列には、角括弧や疑問符などの正規表現の特殊文字が含まれています。次のように、文字列[hello]
をgoodbye
で置換しようとします。
これは明らかに意図した結果ではありません。このようなシナリオは、文字列内で正規表現の特殊文字([hello]
)を使用した場合に発生します。
この問題を回避するには、2つのオプションがあります。それぞれの文字の前にバックスラッシュを追加して特殊文字をエスケープするか、Escape()
メソッドを使用することです。
以下では、各特殊文字をバックスラッシュでエスケープした場合の効果が示されています。
または、より推奨される方法として、正規表現の型のEscape()
メソッドを使用してすべての特殊文字を自動的に削除することができます。
できる限り
Escape()
メソッドを使用するべきです。それによって、特殊文字を覚える必要がなくなります。
マッチ/キャプチャグループの使用
これまでの例では、このチュートリアルでは、別の文字列で置き換えるためにリテラル文字列を使用してきました。hi
やgoodbye
を使用してきました。しかし、PowerShellが見つけた文字列を置き換えるために、1つまたは複数の文字を使用したい場合はどうでしょうか。これには、一致またはキャプチャグループを使用する必要があります。
正規表現には、キャプチャグループとバックリファレンスという概念があります。キャプチャグループを使用すると、他の場所で参照するために文字列をキャプチャできます。PowerShellは、replace
演算子を使用してこれらの機能を活用します。
例えば、いくつかの異なる値が含まれる可能性がある文字列があるかもしれません。
以下のように、文字列の最初の部分と2番目の部分を入れ替えたいとします。
この操作を行うために、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.
以下に例を示します。
上記の例では、正規表現のキャプチャグループがマッチ(hello world
)と(you sexy beast
)をカッコで囲んでいるのが見えます。そして、置換のために、hello world
が最初に左から右にマッチしたので、$1
がバックリファレンスラベルとして、you sexy beast
が$2
として返されます。
PowerShellがそれぞれのマッチの値を知ったら、これらの参照を置換テキスト内で任意の方法で使用できます。この例では、$2,$1
は位置を入れ替えます。
名前付きマッチグループの使用
マッチ値を参照するために$1
、$2
などの数字のプレースホルダを使用したくない場合、ラベルまたは名前も使用できます。左から右に数える必要がある参照が何を意味するかを避けるために、名前を使用することができます。
名前を参照として使用するには、まずマッチ文字列の各マッチに対してラベルを定義する必要があります。それには、キャプチャグループを(?<label><regex>)
のように定義する必要があります。ここで、label
は名前であり、<regex>
は使用している正規表現です。
名前を定義したら、置換文字列でドル記号を使用し、名前を中括弧で囲んで参照することができます。例えば、${label}
です。
このテクニックのデモンストレーションを以下で見ることができます。
結論
学んだ通り、PowerShellの置換演算子はさまざまな方法で文字、テキスト、文字列を置換することができます。単純な置換を行う場合は、replace()
メソッドを使用することができますが、より高度なマッチングと置換が必要な場合は常にreplace
演算子を使用してください。