正規表現 雑メモ

ちょろっとPerl正規表現で遊んでたので、適当に書いとく。

式を文字列として書くなど

use strict;
use warnings;
use 5.10.1;

# 普通
say 'xyz' =~ /y/; # 1
say 'xyz' =~ 'y'; # 1

# メタ文字
say 'xyz' =~ /.yz/; # 1
say 'xyz' =~ '.yz'; # 1

# オプション
say 'XYZ' =~ /.yz/i; # 1
# say 'XYZ' =~ '.yz'; # コンパイルエラー。m{}を使う。
say 'XYZ' =~ m'.yz'i; # 1

# プリコンパイル
my $re = qr/yz/i;
say $re; # (?i-xsm:yz)

say 'XYZ' =~ $re; # 1
say 'XYZ' =~ /$re/; # 1
say 'XYZ' =~ /$re$/; # 1
say 'XYZ' =~ "$re\$"; # 1 

my $re2 = qr/$re$/;
my $re3 = "$re\$";
say $re2; # (?-xism:(?i-xsm:yz)$)
say $re3; # (?i-xsm:yz)$
say 'XYZ' =~ $re2; # 1
say 'XYZ' =~ $re3; # 1

文字列によるマッチングも出来るようなので、qrコンパイル済みのものでも、ちょっと拡張して使うことができたりするみたい。
(?有効オプション-無効オプション:文字列)みたいなフォーマットなら何でも良いらしい?
ドキュメントにも書いてないっぽい?(英語読めない)
よくわからん。

マッチング中に任意のPerlコードを実行

http://perldoc.perl.org/perlre.htm

say 'xxx'=~qr/xx(?{print 'HOGE'})x/; # HOGE1
say 'xxx'=~qr/(??{'x' x 3})/; # 1


コード実行を含んだ正規表現の文字列をマッチングで使うことは普通はできない。

my $str= q{(?{print 'HOGE'})};
print 'xxx'=~/$str/;

# Eval-group not allowed at runtime, use re 'eval' in regex m/(?{print 'HOGE'})/ at - line 2.
my $str= q{((?-xism:(?{print 'HOGE'}))};
print 'xxx'=~$str; # qr/(?{print 'HOGE'})/をした文字列を埋め込んでもダメ。

# Eval-group not allowed at runtime, use re 'eval' in regex m/(?{print 'HOGE'})/ at - line 2.
my $str= q{(?{print 'HOGE'})};
my $regex = qr/$str/; # コンパイル時に引っかかるので当然ダメ
print 'xxx'=~qr/$regex/;
# Eval-group not allowed at runtime, use re 'eval' in regex m/(?{print 'HOGE'})/ at - line 2.


どうしても使いたい場合は use re 'eval';をつける
http://perldoc.perl.org/perlre.html#Combining-RE-Pieces

use re 'eval';
my $regex = q{(?{print 'HOGE'})};
print 'xxx'=~qr/$regex/; # HOGE1


マッチング中にコード実行する使い道が思いつきにくいけども。
検索か何かでユーザの入力を、そのまま正規表現に使うのはやめましょう。