web-dev-qa-db-ja.com

すべてのパターンマッチを変更するPerlコマンドライン正規表現

Perlコマンドラインで一致したパターンに対していくつかの算術演算を使用しようとしています。私は1つの試合でそれを行うことができますが、すべてではありません。

str="a1b2c3"
Perl -pe 's/\d+/$&+1/e'  <<<"$str"
a2b2c3

$&は、最初に一致した数字1を指します。すべての数字に1を追加するにはどうすればよいですか?すべての一致したパターンを表す$&のような変数はありますか?または、複数の数字に一致するように正規表現を変更する必要があります。

与えられた入力に対して、私は次のような出力を期待しています

a2b3c4
5
Inian
_str="a1b2c3"
Perl -pe 's/\d+/$&+1/ge' <<<"$str"
_

置換にgフラグを使用すると、Perlは入力行の重複しない一致ごとに式を適用します。

Nitpick:実際にはここに関与するキャプチャグループはありません(元の質問はキャプチャグループに言及しました)。 Perl変数_$&_は、「最後に成功したパターンマッチで一致した文字列」です。これは、例えばとは異なります。 _$1_や_$2_などは、対応するキャプチャグループ(括弧で囲まれた式)に一致する文字列を参照します。 _\d+_にはキャプチャグループはありませんが、代わりにs/(\d+)/$1+1/geを使用して、単一のキャプチャグループを使用することもできます。

結果に関して、s/(\d+)/$1+1/geと_s/\d+/$&+1/ge_の間に違いはありません。この短いインラインPerlスクリプトでは、どちらを使用するかを選択しても違いはありませんが、通常、少なくとも多くの正規表現操作を行うより長いPerlプログラムでは_$&_の使用を避けたいです。古いPerlリリースを使用している場合。

_perldoc perlvar_から(私の強調):

パフォーマンスの問題

伝統的にPerlでは、3つの変数_$`_、_$&_または_$'_(またはそれらの_use English_に相当するもの)のコード内の任意の場所での使用コードがその後これらの変数の1つにアクセスする可能性がある場合に備えて、後続のすべての成功したパターン一致により、一致した文字列のコピーを作成しました。これにより、プログラム全体でパフォーマンスが大幅に低下するため、一般的にこれらの変数の使用は推奨されていません。

[...]

Perl 5.20.0では、新しいコピーオンライトシステムがデフォルトで有効になりました。これにより、これら3つの変数のすべてのパフォーマンスの問題が最終的に修正され、どこでも安全に使用できるようになります。

10
Kusalananda

実際にzshシェルを使用している場合(<<<zshから派生した非標準の演算子ですが、他のいくつかのシェルにコピーされています)、そのためにPerlを呼び出す必要がないことに注意してください。

できるよ:

set -o extendedglob # for (#m) below
printf '%s\n' ${str//(#m)<->/$((MATCH+1))}

どこ

  • (#m)は、$MATCHPerl$&に相当)での一致全体のキャプチャをオンにします
  • <->は、10進数の任意のシーケンスと一致します(<5-12>に似ていますが、範囲がありません)。
2