Perlの正規表現で複数行にマッチさせる方法

Perlの正規表現で複数行にマッチさせる方法

Posted at May 28,2013 1:55 AM
Tag:[Perl]

Perlの正規表現で複数行にマッチさせる方法を紹介します。

1.改行を含めてマッチさせる

複数行にマッチさせるには、単に改行文字「\r\n」や「\n」を正規表現に含めるだけです。

ですが、そもそも対象のテキストに改行が含まれていることが前提になります。

次のように、ファイルをオープンしてファイルハンドルをwhile文でループさせるだけでは改行は含まれません。ファイルハンドルに1行ずつ配列として読み込まれるためです。

open my $fh, $file;
while (<$fh>) {
    # ...
}

改行にマッチさせる正規表現は知っていても、ファイルを一括読み込みさせる方法が分からない方は、3項に示す一括読み込みを行ってください。

2.改行を含めてマッチさせる(他の方法)

1項の他に、改行を含めたマッチ方法としては、mオプションまたはsオプションの利用があります。

sオプション(または1行モード(Single line mode))はワイルドカードのピリオド「.」が改行にもマッチするようになります。

$str =~ /~/s;

例として、sオプションを使って以下の複数行テキストの中にある赤色部分の3行を取り出してみます。

AUTHOR: mtbook
TITLE: シンポジウム2010
BASENAME: 2010
STATUS: Publish
ALLOW COMMENTS: 1
CONVERT BREAKS: __default__
CATEGORY: イベント
DATE: 04/03/2012 05:44:32 PM

この場合、次のように書くとよいでしょう。

#!/usr/bin/perl
 
use strict;
 
my $data = <<EOF;
AUTHOR: mtbook
TITLE: シンポジウム2010
BASENAME: 2010
STATUS: Publish
ALLOW COMMENTS: 1
CONVERT BREAKS: __default__
CATEGORY: イベント
DATE: 04/03/2012 05:44:32 PM
EOF
 
if ($data =~ /.*(BASENAME: 2010.STATUS: Publish.ALLOW COMMENTS: 1\n).*/s) {
    print $1;
}

mオプション(または複数行モード(Multiple line mode))は、文字列を複数行として扱えるようになります。つまり、正規表現に改行「\n」を記述することで改行にマッチするようになります。

$str =~ /~/m;

なお、mオプションは正規表現中に「^」や「$」を使って先頭や末尾を指定しないとマッチしません。

2.改行を含めてマッチさせる処理を繰り返す

改行を含めてマッチさせる処理を繰り返すには、パターンマッチ演算子にgオプションをつけて、while文で繰り返すだけです。

以下はmオプションを利用した例です。

#!/usr/bin/perl
 
use strict;
 
my $file = shift;
open my $fh, $file;
my $content = do { local $/; <$fh> };
 
while ($content =~ /(^BASENAME: .*$)/gm) {
    print $1;
}

このコードに次のようなテキストファイルを読み込ませれば、指定したパターンにマッチしなくなくなるまで繰り返し処理してくれます。

--------
AUTHOR: mtbook
TITLE: シンポジウム2010
BASENAME: 2010
STATUS: Publish
ALLOW COMMENTS: 1
CONVERT BREAKS: __default__
CATEGORY: イベント
DATE: 04/03/2012 05:44:32 PM
--------
AUTHOR: mtbook
TITLE: ホームページリニューアル
BASENAME: post
STATUS: Publish
ALLOW COMMENTS: 1
CONVERT BREAKS: __default__
CATEGORY: お知らせ
DATE: 03/17/2012 05:43:43 PM
--------
AUTHOR: mtbook
TITLE: 業務提携に関するお知らせ
BASENAME: post-8
STATUS: Publish
ALLOW COMMENTS: 1
CONVERT BREAKS: __default__
CATEGORY: お知らせ
DATE: 08/10/2013 05:46:00 PM
--------

3.複数行を一括読み込みする

外部ファイルを複数行として処理するためには、2項で示したように読み込んだファイルを一括読み込みさせる必要があります。

open my $fh, $file;
my $content = do { local $/; <$fh> };

「$/」は特殊変数で、改行区切りを一時的に無効にする機能があります。そして1行分のデータを読み込みます。

2013.05.28
本文を修正しました。

関連記事
zenback
人気エントリー
トラックバックURL


コメントする
greeting

*必須

*必須(非表示)


ご質問のコメントの回答については、内容あるいは多忙の場合、1週間以上かかる場合があります。また、すべてのご質問にはお答えできない可能性があります。予めご了承ください。

太字イタリックアンダーラインハイパーリンク引用
[サインインしない場合はここにCAPTCHAを表示します]

コメント投稿後にScript Errorや500エラーが表示された場合は、すぐに再送信せず、ブラウザの「戻る」ボタンで一旦エントリーのページに戻り(プレビュー画面で投稿した場合は、投稿内容をマウスコピーしてからエントリーのページに戻り)、ブラウザをリロードして投稿コメントが反映されていることを確認してください。

コメント欄に(X)HTMLタグやMTタグを記述される場合、「<」は「&lt;」、「>」は「&gt;」と入力してください。例えば「<$MTBlogURL$>」は「&lt;$MTBlogURL$&gt;」となります(全て半角文字)