もうちょっとましなパズルをしよう.今度はある文字列の一部に文字列 (パターンと呼ぶ)が一致するかどうかを見ることにしてみよう. たとえば,パターン"abc"は文字列"abcdef"とマッチする.
これだけだと,全然面白くないので,パターンに役のある文字を導入しよう. 以下が特別な役のある文字だ.
[ ] 文字範囲指定.[a-z]はaからzまでのいずれか \w 英数字.[0-9A-Za-z_]と同じ \W 非英数字 \s 空白文字.[ \t\n\r\f]と同じ \S 非空白文字 \d 数字.[0-9] と同じ \D 非数字 \b 語境界文字(範囲指定外) \B 非語境界文字 \b 後退(0x08)(範囲指定内) * 直前の表現の0回以上の繰り返し + 直前の表現の1回以上の繰り返し {m,n} 直前の表現のm回からn回の繰り返し ? 直前の表現の0または1回の繰り返し | 選択 ( ) 表現をまとめる
たとえば,「^f[a-z]+」は「fからはじまるaからzまでの文字の繰り返し」 であり,"foobar"や"fool"などと一致する.こういう役のある一致を正規表現 (regular expression)と呼ぶ.正規表現は文字列の検索の時に役に立つので, UNIXの世界ではいろいろと使われている. 代表的なのはgrepと呼ばれるプログラムだ.
正規表現を身につけるために,ちょっとしたプログラムを使ってみ よう.以下のプログラムをregx.rbという名前でセーブして実行し てみよう.
st = "\033[7m" en = "\033[m"
while TRUE print "str> " STDOUT.flush str = gets break if not str str.chop! print "pat> " STDOUT.flush re = gets break if not re re.chop! str.gsub! re, "#{st}\\&#{en}" print str, "\n" end print "\n"
これは最初に入力した文字列のうち,次に入力した正規表現に
一致する部分を反転するプログラムだ.
細かい意味はあとで説明するから今は気にしないでおこう.
以下は実行例だ.
str> foobar pat> ^fo+ foobar ~~~# 実際はfooの部分は反転している.
いろいろ試してみよう.
str> abc012dbcd555 pat> \d abc012dbcd555 ~~~ ~~~このプログラムは複数の一致を検出できるようになっている.
str> foozboozer pat> f.*z foozboozer ~~~~~~~~
foozではなく,foozboozにマッチするのは正規表現というのはより 長い一致を選ぶようになっているからだ.
正規表現はとてもひとめでは意味の分からないようなパターンも書 ける.
str> Wed Feb 7 08:58:04 JST 1996 pat> [0-9]+:[0-9]+(:[0-9]+)? Wed Feb 7 08:58:04 JST 1996 ~~~~~~~~
rubyのプログラムの中では正規表現は`/'でくくる.またいくつか のメソッドは文字列を正規表現に自動的に変換してくれる.
ruby> "abcdef" =~ /d/ 3 ruby> "abcdef" =~ "d" 3 ruby> "aaaaaa" =~ /d/ FALSE ruby> "aaaaaa" =~ "d" FALSE
`=~'は正規表現の比較を行う演算子で,一致した時に一致した位置 を返す.