woshidan's blog

あいとゆうきとITと、とっておきの話。

今日からはじめよう、正規表現 in Ruby(基本のき〜文字クラス編)

コンソールで正規表現を試す

初心者:うーん、irbで、ほにゃほにゃ、する。いや、返り値を取得してpとか。

えーと……、ほにゃほにゃ、しないでください。

あなた、プログラマの卵でしょう。

とりあえず、

/正規表現/.match("マッチングさせたい文字列")

を入力するといいです。

たとえば。

/[abcdefg]/.match("string") => #<MatchData "g">

これ知らないと、余計な時間が3秒くらい試行のたびにかかります。

インターネットの正規表現チェッカーもありますが、直接Rubyに聞きましょう(※1)。

ネットのつながらない場所でも出来るし。

あと、別にpとかしなくてもコンソールに処理内容を入力したら、マッチング結果は出ます。便利だ!

 

正規表現で変数を使う

初心者:え、っと。正規表現の固定の部分をあらかじめ、変数を使って作る処理を書いてから、+とか使って//の中に入れたらいいんでしたっけ?

 

正規表現の中で固定の文字列はリテラルといいます。

 

それでも一応出来るけれど、もっと簡単に書く方法があります。

このへんは特に言語によって若干変わりそうですが、

Ruby正規表現の中に変数を組み込みたいときは//の中で、

#{変数名}

という書き方をします。たとえば、例は上のページからの引用になりますが、

place = "東京都"
/#{place}/.match("Go to 東京都") # => #<MatchData "東京都">

という具合です。メタ文字(いわゆる記号文字、いちおう)を使うときは、少し注意が必要で、これも上のページからの引用で、

number = "(\\d+)"
operator = "(\\+|-|\\*|/)"
/#{number}#{operator}#{number}/.match("43+291")
# => #<MatchData "43+291" 1:"43" 2:"+" 3:"291">

となっています。実際コンソールで入力すると分かるのだけれど、

文字列オブジェクトが作られたときに\が1個取れてしまうので、変数でメタ文字を使う場合は\を1個多めにつける必要があります。

あと、文字列としてはスラッシュが特殊文字として扱われないのかもしれません。

で、上の正規表現を変数を使わずに入力するとこうなります。

/(\d+)(\+|-|\*|\/)(\d+)/

[ ]文字クラスを使う

初心者:あー、鍵括弧の中の奴か。うーん、なんとなく入れたい文字を並べとくんでしょう。

[abc]みたいなのは文字クラスといいます、実は。

まあ、丸括弧と区別がついているならまだマシでしょう。

 []は中に並べた文字のどれかを一回だけマッチさせます。

たとえば以下の場合だと、

/[abcde]/.match("abcdefg") => #<MatchData "a">

マッチングされるのはの中にあるa,b,c,d,eの中で最初に現れたaだけであり、の中に含まれているけれどaより後ろのb,c,d,eはマッチングされません。

 

よく、何か言語やフレームワークなどのマニュアルで正規表現というものがあります、と紹介されるときはいつも

/[\d]+/.match("1234") => #<MatchData "1234">

という具合に後ろに繰り返しを表す量指定子がついているのがほとんどなので、

正規表現に不慣れな人はなんとなくについて

一定の種類の文字繰り返し取得するときに使うのだろう

というイメージがあるのかもしれません。が、

は一定の種類の文字を一文字だけ取得するときに使うもので、[]の中に直接取得したい文字を並べていくという形で使います。

こんな感じ。

/W[aeiou]rd/.match("Word") => #<MatchData "Word">
/W[aeiou]rd/.match("Ward") => #<MatchData "Ward">
/W[aeiou]rd/.match("Wird Werd")=> #<MatchData "Wird">

よく分かってない人:なるほど、はリテラルの中に枝分かれの部分を作るんですね。

f:id:woshidan:20140414002457p:plain

こんな感じ。 

 

そうですね。

君は早くスライドを作るソフトをmacの方にも入れましょうね。

 

で、繰り返す部分に対しては+や*が表現していますが、詳しくは後にしましょう。

 

で、の中に列挙していく文字には、

よく使われるパターンに対しては略記法があり

\d =>半角数字
\w =>半角英数字
\s =>空白文字

などがあります。

これをそのまま正規表現とイメージしている人もいるかもしれませんね。

ここで、\の後ろの文字をそれぞれを大文字にすると

\D =>半角数字以外の文字

みたいに、小文字のときに指定した文字以外の文字を指定することになります。

 

初心者:全角スペースとかは検出できないんですか?

 

それですね。

Ruby正規表現では基本的にASCIIコードで扱える文字しか扱えなませんから、

その中に含まれない「全角アルファベット」「全角空白」「全角数字」は扱えないんですよ。

プログラムの中では、基本的に使わないほうがいい文字だから使わないようにしましょう、としか言えないですが、webページの見出しとか他人の書いた日本語の文章を表示する部分についてはそういうわけにはいきませんから、

もしそういった部分を正規表現で扱う事がある場合は、少し覚えておいた方がいいかもしれませんね。そんなにほとんどないとは思うけど。

まあ、いろんなエディタは設定で全角スペースを強調表示できるようになっているから、そういうのも利用してみたらいいんじゃないでしょうか。