Perl:正規表現における () と (?:) の違い
技術ドキュメント目次 -> Perl -> 正規表現における () と (?:) の違い本技術ドキュメントは、2002~2004年頃に作成したものが多いです。
内容が古くなっていることもあるかと思いますが、ご了承ください。
【低価格SSL証明書】弊社運営の低価格SSL証明書販売サイト、翌月末払いなど請求書払いも可能。
◆ 正規表現における ()
正規表現による操作をPerlで行う際に、$somevar といった変数値をパターンとして記述することもよくあるかと思います。
また、その際、変数であることを示す $ が正規表現の終端マーク(^ が先端マーク
で $ が終端マーク)とまぎらわしいので、変数値を () でくくってパターンとして
記述することもよくあるかと思います。
その際、()でくくった部分にマッチする文字列は、
$1 $2 といった特殊な変数に値がコピーされています。
例えば次のようなコードがあった場合、
my $str = "Hello World!"; my $reg = "Hello"; if ($str =~ m|^($reg)\s+([a-zA-Z]+)|) { print "Match !!\n"; print "1: $1\n"; print "2: $2\n"; } else { print "NOT Match !!\n"; } |
それを実行すると次のようになります。
$ perl test.pl Match !! 1: Hello 2: World $ |
◆ 正規表現における () と (?:) の違い
(?:) は () と同じようなことを行えるのですが、(?:) の場合は $1 $2 への値のコピーが行われませんので、
その分高速に動作します。
$1 $2 への値のコピーを必要としていないときには、
() でなくて (?:) を使用することをオススメします。
例えば次のようなコードがあった場合、
my $str = "Hello World!"; my $reg = "Hello"; if ($str =~ m|^(?:$reg)\s+([a-zA-Z]+)|) { print "Match !!\n"; print "1: $1\n"; print "2: $2\n"; } else { print "NOT Match !!\n"; } |
それを実行すると次のようになります。
$ perl test.pl Match !! 1: World 2: $ |
上記の例では、m|^(?:$reg)\s+([a-zA-Z]+)| としていましたが、
それを、m|^(?:$reg)\s+(?:[a-zA-Z]+)| に代えると、
正規表現実行後に $1 も $2 も値が空になっています。
■ Perl についての他のドキュメント
- %SIGによるシグナルの制御
- CSV等区切り文字で連結されたデータを操作(joinとsplit)
- Digest::MD5
- Digest::SHA1
- localtime()やgmtime()をスカラーで評価
- 正規表現において // の代わりに || を使用する
- 正規表現における () と (?:) の違い
- 配列・連想配列を条件に基づいてソート(sort)
■ 他のグループのドキュメント
Apache / Linux / FreeBSD / OpenSSL / Perl / HTTPプロトコル / Jakarta Tomcat / Java / NetBSD / Oracle / PostgreSQL / UNIX の C言語 / UNIX のコマンド / Windows / bind / システム運用TIPS