- コピー - - 目次

正規表現


もうちょっとましなパズルをしよう.今度はある文字列の一部に文字列 (パターンと呼ぶ)が一致するかどうかを見ることにしてみよう. たとえば,パターン"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

`=~'は正規表現の比較を行う演算子で,一致した時に一致した位置 を返す.


- コピー - - 目次