RubyではPerlとほぼ互換性のある正規表現を使用して文字列のパターンマッチを行うことができます。

正規表現を使う

Rubyでは正規表現を扱う場合Regexpクラスを使用します。スクリプト中で、

 r = Regexp.new("ruby") 

のように明示的にRegexpのインスタンスを生成することもできますし、

 /ruby/

のようにリテラルで記述することもできます。

正規表現を条件式で使う

if文などの条件式に正規表現を使用することが出来ます。以下の例は、strの先頭がabcの場合、条件式が真となります。

=~はRegexpクラスのメソッドでマッチした場合にそのインデックス(位置)を返却します。

 if /^abc/ =~ str
   puts "match"
 end

Perl 風に書く

=~ は String クラスのメソッドでもあるので以下のようにも書けます。

 if str =~ /^abc/
   puts "match"
 end

文字にマッチさせる

正規表現では文字そのものを表現するリテラルと、特別な意味を持つメタ文字を使用し特定のパターンにマッチさせることができます。

 if /abc/ =~ str
   puts "match"
 end

この例ではstr中にabcという文字列が含まれている場合、matchという文字列を標準出力へ出力します。

このような単純な条件でなく行頭が#で始まるか? 電話番号が含まれるか?など複雑な形式を表現する場合に、メタ文字を使います。

Rubyで使用できる主要なメタ文字の一覧を以下に示します。

^ 行頭にマッチします。
$ 行末にマッチします。
. 改行を除く任意の1文字にマッチします。
[…] []内のいずれか1文字にマッチします。
[^…] []内に含まれない1文字にマッチします。
* 直前の表現の0回以上の繰り返しにマッチします。
+ 直前の表現の1回以上の繰り返しにマッチします。
? 直前の表現の0回または1回の繰り返しにマッチします。
{n} 直前の表現n回の繰り返しにマッチします。
{n,} 直前に表現にn回以上の繰り返しにマッチします。
{n,m} 直前に表現にn回以上の繰り返しにマッチします。
a|b aまたはbにマッチします。
(…) 正規表現をグループ化する。マッチしたテキストは記憶されます。
\w 英数字と_にマッチします。
\W 英数字と_以外にマッチします。
\s 空白文字(スペース、タブ)にマッチします。
\S 空白文字(スペース、タブ)以外にマッチします。
\d 数字にマッチします。
\D 数字以外にマッチします。
[ぁ-ん] ひらがなだけ
[ァ-ヴ] カタカナだけ
[一-龠] UTF-8の漢字だけ
[亜-煕] sjisの漢字だけ

繰り返し文字とマッチさせる

メタ文字の、+、?などを使用して繰り返し文字とマッチさせることができます。は直前の正規表現の0回以上の繰り返しとマッチします。

以下の例では、直前の文字aが0回以上繰り返しの後にcという文字が存在する場合にマッチします。

 /a*c/ =~ "abc" #=> マッチする
 /a*c/ =~ "ac" #=> マッチする
 /a*c/ =~ "aaaaaac" #=> マッチする
 /a*c/ =~ "c" #=> マッチする
 /a*c/ =~ "abcccccc" #=> マッチする
 /a*c/ =~ "abd" #=> マッチしない

+は直前の正規表現の1回以上の繰り返しとマッチします(最低でも1回以上の繰り返しが必要)。

以下の例では、直前の文字aが1回以上繰り返した後にcという文字が存在する場合にマッチします。

 /a+c/ =~ "abc" #=> マッチしない
 /a+c/ =~ "ac" #=> マッチする
 /a+c/ =~ "aaaaaac" #=> マッチする
 /a+c/ =~ "c" #=> マッチしない
 /a+c/ =~ "abccccc" #=> マッチしない
 /a+c/ =~ "abd" #=> マッチしない

?は直前の正規表現の0回、または1回の繰り返しとマッチします。

以下の例では、直前の文字aが0回または1回繰り返した後にcという文字が存在する場合にマッチします。

 /a?c/ =~ "abc" #=> マッチする
 /a?c/ =~ "ac" #=> マッチする
 /a?c/ =~ "aaaaaac" #=> マッチする
 /a?c/ =~ "c" #=> マッチする
 /a?c/ =~ "abccccc" #=> マッチする
 /a?c/ =~ "abd" #=> マッチしない

数字だけ・アルファベットだけとマッチさせる

文字クラスを使用すると数字だけ、アルファベットだけ、AかBかZのどれかなど、複数文字中の任意の1文字を表現することができます。

文字クラスを指定する場合、複数の文字を[]で括ります。

 /[ABZ]/ =~ "A" #=> マッチする
 /[ABZ]/ =~ "Z" #=> マッチする
 /[ABZ]/ =~ "Q" #=> マッチしない

[]内で-を使用すると文字の範囲を示します。[A-Z]とすればAからZまで、[0-9]とすれば0から9までの数字を表現することができます。

 /[0-9]/ =~ "5" #=> マッチする
 /[0-9]/ =~ "A" #=> マッチしない
 /[A-Z]/ =~ "A" #=> マッチする
 /[A-Z]/ =~ "5" #=> マッチしない
 /[A-Z]/ =~ "a" #=> マッチしない

[]内で^を指定するとそれ「以外」を表現することができます。

 /[^0-9]/ =~ "A" #=> マッチする
 /[^0-9]/ =~ "5" #=> マッチしない

改行コードを含む文字列にマッチさせる

メタ文字の . に改行コードをマッチさせるには、正規表現式の末尾に m 修飾子を付けて複数行モードにします。

 /abc.*xyz/m  =~ multiLines    #=> abc と xyz の間に改行があってもマッチする

n番めのマッチを見つける

正規表現のグルーピングを使用し、正規表現内のn番めのグループにマッチした文字列という処理を記述することができます。

正規表現内で()で括られた文字列がグループになり、n番目の要素を参照する場合、$nと記述します。

 /1(.)3(.)5(.)/ =~ "123456" #=> $1="2", $2="4", $3= "6"
 
 /([a-z]+),([\d\-]+),(\S+)/ =~ "take,045-111-2234,Yokohama"
   #=> $1="take", $2="045-111-2234", $3="Yokohama"

正規表現を使って文字列を置き換える

String#subメソッド、String#gsubメソッドは文字列の置換を行いますが、置換される文字列の指定に正規表現を使用することができます。

 str = "Copyright 2001 by TAKEUCHI Hitoshi.".sub(/[A-Za-z]*right/, "Copyleft")
   #=> "Copyleft 2001 by TAKEUCHI Hitoshi."

パターンで区切られたレコードを読む

String#splitメソッドは文字列を指定したパターンにより分割し、結果を配列へ格納することができます。

そのため、CSVファイルなど特定のパターンにより区切られたレコードを解析する際に便利です。

 "001,TAKEUCHI Hitoshi, Yokohama".split(/\s*,\s*/) #=> ["001", "TAKEUCHI Hitoshi", "Yokohama"]

マッチした文字列を全て抜き出して配列へ格納する

String#scanメソッドは文字列中で任意のパターンにマッチするものを全て抜き出し、配列へ格納することができます。

 p "hoge:045-111-2222 boke:045-222-2222".scan(/[\d\-]+/)

  #=> ["045-111-2222", "045-222-2222"]

正規表現の中にグルーピングの括弧を使うと,それぞれにマッチした文字列の配列を要素とする配列が得られます。

 p "hoge:045-111-2222 boke:045-222-2222".scan(/(\S+):([\d\-]+)/)
 
 #=> [["hoge", "045-111-2222"], ["boke", "045-222-2222"]]

正規表現にコメントを付ける

正規表現の生成時のオプションにxを指定すると、正規表現中の空白文字(スペース、タブ、改行など)を無視し、また、#によるコメントを付けることができます。

 r = /(\S+):       # 名前
      ([\d\-]+)    # 電話番号
     /x
 
 p "hoge:045-111-2222 boke:045-222-2222".scan(r)
   #=> [["hoge", "045-111-2222"], ["boke", "045-222-2222"]]

正規表現内でString型変数を使う

正規表現内で、String型変数を使用する際には、#{変数名}の様に、変数を#{}で括ってやる必要が有ります。

 regEx = "^a"             # 先頭のaにマッチする、正規表現を表すString型変数 
 p "abc".scan(/regEx/)    #=>[]  正規表現 "regEx" とはマッチしない
 p "abc".scan(/#{regEx}/) #=>["a"] 正規表現 "^a" とマッチ