2007年1月 8日
Rubyの正規表現「 . (ピリオド or ドット)」
正規表現では あらゆるパターンを表現するために 特殊な記号や文字を駆使することになる。 それらの正規表現記号のことを「メタ文字」という。最も基本的はメタ文字のひとつが「 . 」。「ピリオド」とか「ドット」とか呼ばれている。 Rubyマニュアルの 「正規表現」の 説明によると、「改行を除く任意の 1 文字にマッチします。」 とある。 簡単な正規表現ではあるが、 Rubyスクリプトによる例題を挙げてみる。
p "The quick brown fox" =~ /quick/ #=> 4 p Regexp.last_match[0] #=> "quick"まずは、メタ文字を使用していない例。 文字列「"The quick brown fox"」において 正規表現である「/quick/」 を 「=~」 によってマッチするかどうか判断している。 マッチしていたら、マッチしていた位置を 行頭を「0(ゼロ)」として数えた値を返す。 よって、この例では、「4」となるので それを 「p」メッソドで表示している。 「#」マークから右側はコメント。 「=>」は なくても構わないのだが、 Rubyの世界では実行結果を示す場合にはこのマークをつける慣例になっているようだ。 ここでもこの慣習に習ってつけている。 結果をコメントとして表示している。
2行目は「 Regexp.last_match[0] 」という変数を表示させている。 これは、最後に成功した正規表現のパターンマッチでマッチした文字列を表す変数(配列?)。 これを「 $& 」と書いても同じ結果になるのだが、 なれない人が見ると 何のことだか わかりずらいので ここでは あえて 「 Regexp.last_match[0] 」としてみた。
p "The quick brown fox" =~ /qu.ck/ #=> 4 p Regexp.last_match[0] #=> "quick"次の例では、任意の 1 文字にマッチする メタ文字「 . (ピリオド or ドット)」を 正規表現の中に使ってみた。 正規表現を「/qu.ck/」としたので、 これは、「qu」で始まり、どんな文字でもいいので1文字あって、 続けて「ck」で終わる5文字の文字列が存在するとマッチすることになる。 だから「quick」に限らず「quock」でも「quAck」でもマッチすることになる。
p "The quick brown fox" =~ /qu..ck/ #=> nil p $& #=> nil今度は、マッチしない例。 「qu」で始まり、どんな文字でもいいので2文字あって、 続けて「ck」で終わる6文字の文字列は、 「"The quick brown fox"」中に見当たらないので 結果が「nil」となっている。 2行目で、 「 $& 」を使っているのは 「 Regexp.last_match[0] 」を用いると スクリプトがエラーで止まってしまうので、 ここでは「 $& 」の方を用いた。
p "The quick brown fox" =~ /q...k/ #=> 4 p $& #=> "quick"この例でも、「q...k」が「quick」にマッチするのがわかる。
p "The quick brown fox" =~ /..i../ #=> 4「..i..」も「quick」にマッチする。
このブログでは 自分自身と、それから 正規表現の勉強をこれからはじめる人の参考になるように、 出来るだけ丁寧に説明をつけてみた。 これから、少しずつ メタ文字を増やしていって、 正規表現の実験スクリプト例をどんどんアップしていこうと思う。
【参考リンク】
カテゴリー: Ruby , 正規表現 22:11 | コメント (0) | トラックバック (0)
2007年1月 7日
Rubyの正規表現マッチで利用する「$〜」
Ruby において 正規表現でマッチさせた場合、 ローカルスコープ変数「 $~ 」に自動的にある値がセットされる。 これは、現在のスコープで最後に成功したマッチに関する MatchData オブジェクト を表す。Rubyのマニュアル 「$~」 によると
現在のスコープで最後に成功したマッチに関する MatchData オブジェクトです。 これを設定すると $& や $1 ... $9 などの 値が変化します。 このデータから n 番目のマッチ($n)を取り出すためには $~[n] で 参照できます。とある。 また この「 $~ 」は、「 Regexp.last_match 」 と同じである。 よって、「 $~[0], $~[1], $~[2] 」 も 「 Regexp.last_match[0], Regexp.last_match[1], Regexp.last_match[2] 」 と等価となる。
さらに、上記の説明にも出てきた「 $& 」という変数があり、 これが、Regexp.last_match[0] と同じであり、 マニュアルでの説明には
現在のスコープで最後に成功した正規表現のパターンマッチでマッチした文字列です。 最後のマッチが失敗していた場合には nil。となっている。
これらの例題として
test="The quick brown fox jumps over the lazy dog." p test =~ /(qui)(ck)/ puts p $~ p $~[0], $~[1], $~[2] p $&, $1, $2 puts p Regexp.last_match p Regexp.last_match[0], Regexp.last_match[1], Regexp.last_match[2] p $&, $1, $2というRubyスクリプトを実行してみる。 ここで、2行目の正規表現で「(qui)(ck)」とあるのは 正規表現のグループ化で、 最後に成功したパターンマッチでn番目の括弧にマッチした値が $1, $2 ... に格納される。 これは Regexp.last_match[1], Regexp.last_match[2], ... と同じ。 よって実行結果は
4 #<MatchData:0x2ea421c> "quick" "qui" "ck" "quick" "qui" "ck" #<MatchData:0x2ea421c> "quick" "qui" "ck" "quick" "qui" "ck"となる。この結果から 「 $~ 」と「 Regexp.last_match 」 が、 「 $& 」と「 Regexp.last_match[0] 」 とが 全く同じものである ことが確認できる。
【参考リンク】
カテゴリー: Ruby , 正規表現 22:16 | コメント (0) | トラックバック (0)
2007年1月 6日
Ruby における 「正規表現」
今後「正規表現 (Regular Expression)」について Rubyの上で、いろいろ 検証・実験を行ってゆこうと思っているのだが、 そのために、Ruby における 「正規表現」の取り扱い方法を先に学んでおく。まず、Rubyにおける「正規表現」の表現方法は Ruby「正規表現リテラル」 にあるとおり、
/ で囲まれた文字列は正規表現です。とある。つまり、「/Ruby/」も正規表現だし、「/^.*$/」も正規表現ということになる。 また別の表現方法として、 「Ruby正規表現クラス」にある 「Regexp.compile(string)」または「Regexp.new(string)」によっても表すことができる。 つまり、上記の例は「Regexp.compile("Ruby")」、「Regexp.compile("^.*$")」 または 「Regexp.new("Ruby")」、「Regexp.new("^.*$")」 とも表現できる。
Rubyにおいて 上記の正規表現とマッチを行う方法はいくつかあるが 最もオーソドックスな方法が Ruby「=~」メソッド を利用することである。 マッチが成功すればマッチした位置のインデックスを、そうでなければ nil を返す。 文字列の先頭にマッチした場合には値「0(ゼロ)」 が返されるので注意が必要だ。
Rubyによる 正規表現の試験プログラムの例題として
test="The quick brown fox jumps over the lazy dog." p test =~ /quick/としてみる。 このスクリプトを実際に実行してみると、画面には「4」と表示される。 これは、文字列 "The quick brown..." のうち 「quick」という文字列が 5文字目であり、 先頭の文字を0番から数えると4番目になるため 答えが 「4」となっている。 このスクリプト例は、
test="The quick brown fox jumps over the lazy dog." p test =~ Regexp.compile("quick")と書いても全く同じ結果となる。
ちなみに、文字列に全く含まれていない正規表現とマッチさせる、 例えば
test="The quick brown fox jumps over the lazy dog." p test =~ /abcdef/のような場合は、実行結果に「nil」と表示される。
【参考リンク】
カテゴリー: Ruby , 正規表現 22:52 | コメント (0) | トラックバック (0)
2007年1月 4日
正規表現 (Regular Expression)
私自身、「正規表現」を完璧に把握しているわけではなく 今まで 騙し騙し使いこなしてきたわけだが、 良い機会なので Rubyの習得を兼ねて、 Rubyにおける「正規表現 (Regular Expression)」について このブログ上でまとめて行こうと思っている。
「正規表現」には いろいろな方言があるが、 それについては 各プラットホーム毎に 「正規表現メモ」 に詳しくまとめてある。 その中でも 私のブログでは、基本的に 現行のRubyの実装について 調査・実験してゆこうと思う。
【参考リンク】
- ウィキペディア「正規表現」
- Wikipedia 「Regular expression」
- Ruby「正規表現」
- Ruby「正規表現リテラル」
- Ruby「正規表現」クラス
- 逆引きRuby「パターンマッチ」
- 正規表現メモ
カテゴリー: 正規表現 22:26 | コメント (0) | トラックバック (0)