正規表現のデバッグ

2015年4月12日日曜日

Perl 正規表現

正規表現も複雑になってくるとデバッガでステップ実行のようなことをしたくなってくることがある。
そんなときはPerlのデバッガを使うといい。

perlの起動時にオプションとして-Mre=debugもしくは-Mre=debugcolorを付けると
実行時に生成された正規表現オブジェクトの内容とマッチング経過が表示される。

例えば、"[tD]o\sBe\sDo"という正規表現を"to Be is to Do to Do is to Be Do Be Do Be Do"に適用すると
以下のように出力される。

$ perl -Mre=debug -e 'qq/to Be is to Do to Do is to Be Do Be Do Be Do/ =~ /[tD]o\sBe\sDo/'

Compiling REx "[tD]o\sBe\sDo"
Final program:
   1: ANYOF[Dt][] (12)
  12: EXACT <o> (14)
  14: POSIXD[\s] (15)
  15: EXACT <Be> (17)
  17: POSIXD[\s] (18)
  18: EXACT <Do> (20)
  20: END (0)
anchored "Be" at 3 (checking anchored) stclass ANYOF[Dt][] minlen 8 
Guessing start of match in sv for REx "[tD]o\sBe\sDo" against "to Be is to Do to Do is to Be Do Be Do Be Do"
Found anchored substr "Be" at offset 3...
start_shift: 3 check_at: 3 s: 0 endpos: 1 checked_upto: 0
Does not contradict STCLASS...
Guessed: match at offset 0
Matching REx "[tD]o\sBe\sDo" against "to Be is to Do to Do is to Be Do Be Do Be Do"
   0 <> <to Be is t>         |  1:ANYOF[Dt][](12)
   1 <t> <o Be is to>        | 12:EXACT <o>(14)
   2 <to> < Be is to >       | 14:POSIXD[\s](15)
   3 <to > <Be is to D>      | 15:EXACT <Be>(17)
   5 <to Be> < is to Do >    | 17:POSIXD[\s](18)
   6 <o Be > <is to Do t>    | 18:EXACT <Do>(20)
                                  failed...
  24 <o is > <to Be Do B>    |  1:ANYOF[Dt][](12)
  25 < is t> <o Be Do Be>    | 12:EXACT <o>(14)
  26 <is to> < Be Do Be >    | 14:POSIXD[\s](15)
  27 <s to > <Be Do Be D>    | 15:EXACT <Be>(17)
  29 <to Be> < Do Be Do >    | 17:POSIXD[\s](18)
  30 <o Be > <Do Be Do B>    | 18:EXACT <Do>(20)
  32 <Be Do> < Be Do Be >    | 20:END(0)
Match successful!
Freeing REx: "[tD]o\sBe\sDo"

出力内容の1〜9行目はコンパイルされた正規表現オブジェクトがどのような
10行目以降は実際に文字列に対してマッチングをしていく経過を表している。
ステップ実行とまではいかないが、十分なトレース情報が出力されている。
まず"Be"を検索しにいき(12行目)、そこから3文字戻り、マッチングを続けるが(11〜22行目)、
一度失敗し(23行目)、再度24文字目からマッチングを実行し(24〜30行目)、
マッチングに成功している(31行目)ことがわかる。

あくまで、Perlの実行時の動作なため、別の言語/処理系で同じ動作になる保証はないが、
別の処理系の動作のヒント程度にはなるのではないだろうか。