【Perl】1行分の文字列から、パターンにマッチする回数をカウントするワンライナーほか

投稿日: / 更新日:

例えば、次のような1行の文字列から、helloの出現回数を調べたい場合、

正規表現のグローバルマッチ(gフラグ)を使用することになりますが、今までは大体次のようなワンライナーを書いていました。

ちなみに、}{は[Eskimo greeting](http://search.cpan.org/perldoc/perlsecret#Eskimo_greeting)という慣用句で、これよりも右に書いたコードがあたかもワンライナーのENDブロックのように働き、-p-nスイッチで標準入力の各行に対して行った処理の後処理を行うことができます。上記のワンライナーでは、helloにマッチした都度カウントアップした$countの値を、最後に標準出力へ出力する処理を行っています。

上記のワンライナーを、[Goatse](http://search.cpan.org/perldoc/perlsecret#Goatse)という慣用句を使うことでさらに短く書ける、ということを今回知りました。これにより、ワンライナーを次のように書き直すことができます。

上記のコードのうちの=()=がGoatseです。これは、右側のリスト代入を左側でスカラー変数へ代入(すなわち、スカラーコンテキストで評価)することによって、そのリストの要素数が得られる、というPerlの言語仕様を利用しています。結果として、リストの要素は破棄され、要素数が$countへ代入されます。なお、リストを単純にスカラーコンテキストで評価した場合には、リストの最後の要素しか得られないため、真ん中のかっこ(())が重要となります。

これにより、1つもマッチしなかった場合に0にするコード(||0)も含め、従前のワンライナーに比べて6文字も減らすことができました。ただし、マッチした部分をキャプチャーしなければならないこと、また、何をやっているかが(慣れるまで)分かりにくいこと、がデメリットです。

あと、参考までに、helloの後の数値の合計を出力するワンライナーをご紹介します。

こちらは、数値(\d+)の部分を加算するためにキャプチャーする必要があります。最初のワンライナーと同様、グローバルマッチとEskimo greetingを使用します。Goatseは使用しません。

以上、簡単ですがPerlに関する話題をご紹介しました。

最新情報発信中

Twitterやメルマガでも、Hinemosの保守、
開発、導入、構築やカスタマイズ等の
お役立ち情報を発信しています。
是非ご登録ください。