Perl 「 正規表現 」: s/// 結合演算子と非破壊置換 (0x77)

セラ (perlackline)

2014年02月21日 18:27



目次 - Perl Index



Theme



Perl について、復習を兼ねて断片的な情報を掲載して行く連載その 0x77 回。

Perl 「 正規表現 」( Regular expression )「 s/// 」演算子で結合 ( 拘束 ) 演算子を利用する。それと「 非破壊置換 」について。




s/// で結合演算子「 =~ 」を使う



Perl 「 正規表現 」: 結合演算子 ( =~ ) (0x6a) 」で確認した結合演算子 ( 拘束演算子 ) は、置換演算子「 s/// 」でも利用可能です。

次の例では、$text に格納されている文字列の内「 yes 」を 「 no 」に置き換えています。ワードアンカー「 \b 」を使っているのは、「 eyes 」や「 dyes 」をうっかり置き換えない様にするためです。


$text =~ s/\b(yes)\b/no/g;


これで、$text の中にある「 yes 」はすべて置き換えられるはずです。

便利ですね。

しかしながら、後になって元の文字列を参照したいと考えた場合はどうでしょう。$text の元のデータは、置換によって既に存在しません。

非破壊置換



そういう時には「 非破壊置換 」を使います。

非破壊置換のデータ操作は単純です。置換処理するデータを別の変数にコピーするだけです。


$copy = $origin;
$copy =~ s/PATTERN/REPLACE/g;


これで、$origin のデータは変更されることなく保持されます。

コピーと置換の処理を 1 行にまとめることも可能です。


($copy = $origin) =~ s/PATTERN/REPLACE/g;


ここでも最初に行われるのは $orign から $copy へのデータコピーです。

結合演算子による文字列置換は、$copy に対して行われます。

「 ($copy = $origin) 」の「 ( ) 」を外した場合は、式全体の優先順位が変わり文脈がスカラコンテキストになるため、$copy には置換した回数が代入されます。

Perl 5.14 以上の非破壊置換



Perl の 5.14 以降では、非破壊置換のための修飾子「 /r 」が導入されています。

利用方法は次の通りです。


use 5.014;

$copy = $origin =~ s/PATTERN/REPLACE/rg;


s/// に「 /r 」が追加され、「 ($copy = $origin) 」の「 ( ) 」が不要になりました。

最終的には前の例と同じ結果を得られますが、内部的な処理の動作は変わっています。

修飾子「 /r 」を利用した場合は、データのコピーよりも先に、データの置換が行われます。つまり、置換処理は $origin のデータに対して行い、置換後のデータを $copy に代入するということです。

0x77 -> 0x78 へ



「 非破壊 」という名称はなんとも大げさですが、その内容はというと、なんということはありませんでした。

日本語への翻訳がアレなのかと思いましたが、元の英単語が「 non-destructive 」なのでそうでもないようです。

次回は「 大文字と小文字の変換 」方法を確認します。

参考情報は書籍「 初めての Perl 第 6 版 」を中心に perldoc, Wikipedia および各 Web サイト。それと詳しい先輩。

目次 - Perl Index




















関連記事