Memoize |
BasicWerk
EC Support
Technique
Facebook
|
20140818231352_ruby_regex_assertion_and_mode |
ruby_regex_assertion_and_mode
Perl や PCRE の正規表現に慣れてると、Ruby で躓きやすいのが行頭(^)行末($)アサーションの動作と、シングルラインモードは /s ではなく /m で表現する点だ。
整理しよう。
まずはサンプルを用意。 > str = IO.read "sample.csv" > puts str id,name,price,currency 1,item-A,2980,JPY 2,item-B,900,JPY 3,item-C,3980,JPY 4,item-D,1980,JPY
Ruby では、行頭(^)行末($) は常に、デフォで各行の行頭行末にマッチする。 > str.scan /^.+$/ => ["id,name,price,currency", "1,item-A,2980,JPY", "2,item-B,900,JPY", "3,item-C,3980,JPY", "4,item-D,1980,JPY"]
つまり文字列全体の先頭と末尾にマッチさせたければ \A と \Z を使う。 # おっと、でもこのマッチは失敗する > str.scan /\A.+\Z/ => []
なぜか? 「.」が改行にマッチしないからだ。 改行文字にも . をマッチさせるようにするには /m モードにする。 > str.scan /\A.+\Z/m => ["id,name,price,currency\n1,item-A,2980,JPY\n2,item-B,900,JPY\n3,item-C,3980,JPY\n4,item-D,1980,JPY\n"]
実はこれだけのシンプルなことなんだ。 「Perl/PCRE でいう...は、Ruby では...で」云々と覚えようとするからややこしくなる。
ちなみに Ruby にも /s モードがあるが、これは Perl/PCRE のシングルラインモードとは全然意味が違う。 Ruby の /s モードは「ソースファイルのエンコードが Shift_JIS 以外、かつ、外部から入力された文字列が Shift_JIS であった場合に 正規表現がマッチできるようにする」というもので、つまり「sjis モード」の s ということ。
|
© Shin Nakamura/BasicWerk 2014 |