Ruby 資料一覧

正規表現

2007/6/21更新

対応バージョン: 1.8

マッチングパターン

行頭「^」

文字列の先頭、あるいは改行文字の直後の位置にマッチする。

例)

p "aaa".gsub(/^a/, "1")
=> "1aa"

p "aaa\naaa".gsub(/^a/, "1")
=> "1aa\n1aa"

行末「$」

文字列の末尾、あるいは改行文字の直前の位置にマッチする。

例)

p "aaa".gsub(/a$/, "1")
=> "aa1"

p "aaa\naaa".gsub(/a$/, "1")
=> "aa1\naa1"

英数字「\w」(= [0-9A-Za-z_])

非英数字「\W」(\w以外)

空白文字「\s」(= [\t\n\r\f])

非空白文字「\S」(\s以外)

数字「\d」(= [0-9])

非数字「\D」(\d以外)

ワード境界「\b」

英単語で「limit」はマッチさせたいが「unlimited」はマッチさせたくない場合などにこのワード境界を使用する。

例)

p "limit".gsub(/\blimit\b/, "match")
=> "match"

p "unlimited".gsub(/\blimit\b/, "match")
=> "unlimited" ← マッチしていない

任意の1文字「.」

数字やアルファベット、記号など、文字種は問わず、任意の1文字にマッチする。

例) 「1.3 (1で始まって3で終わる3文字の文字列)」が一致する文字列

113
193
1a3 など

0回以上の繰り返し「*」

いわゆるワイルドカードと同じ文字を使用するが、正規表現においては扱いが微妙に違う。

ワイルドカードでは「任意の複数文字に一致」を意味するが、正規表現では「直前の文字を0回以上繰り返したものに一致」を意味する。

例) 「ab*c」が一致する文字列

ac
abc
abbc
abbbc など

直前の文字の0~1回の繰り返し「?」

例) 「ab?c」に一致する文字列

ac
abc など

直前の文字の1回以上の繰り返し「+」

例) 「ab+c」に一致する文字列

abc
abbc
abbbc など

「ab?c」と違い、acには一致しない

いずれかに一致「[]」

ある規則性を持った文字列のみを一致させたい場合、「[」と「]」を使用する。

この2つで複数の文字を挟むと「中に並べられた文字のどれかに一致」という意味になる。

例えば「母音だけが並んだ文字列」を指定した場合は以下のようにすればよい。

[aiueo][aiueo]*

ここで同じものを2つ並べているのは前述のように「*」が「0回以上の繰り返し」を意味するからである。これは「+」を使用して以下の方法で指定できる。

[aiueo]+

もし並べる文字に規則性があるなら省略形も使える。

始まりの文字と終わりの文字をハイフンでつなげて「[a-z]」とすれば英小文字のいずれか、「[0-9]」とすれば数字のいずれかに一致する。

例) 英単語に一致

[a-zA-Z]+

いずれかの文字以外(否定)「[^」

「いずれかの文字」ではなく、「いずれかの文字以外」という指定もできる。この場合は「[」の直後に「^」を置く。

以下のようにすると「母音以外の1文字」という条件になる。

p "abc".gsub(/[^aiueo]/, "_")
=> "a__"

複数パターンのいずれか「|」

文字ではなく複数のパターンのいずれか、という場合は「|」を使用する。

p "abc".gsub(/abc|def/, "_")
=> "_"

とすれば、「abc」か「def」のどちらかに一致する。

パターンの繰り返し

時として「一致する回数を指定する」という表現をしたくなる。

例えば、ある文字列(プログラム中の変数名など)が9文字以上かどうかを調べたいような場合、通常なら

[a-zA-Z0-9_-][a-zA-Z0-9_-][a-zA-Z0-9_-]
[a-zA-Z0-9_-][a-zA-Z0-9_-][a-zA-Z0-9_-]
[a-zA-Z0-9_-][a-zA-Z0-9_-][a-zA-Z0-9_-]+

と記述するだろうが、このような方法ではタイプミスの可能性もあるし、もっと文字数が増えた場合に作業が困難になるので、以下のようにして回数を指定できる。

[a-zA-z0-9_-]{9,}

「{n}」で直前のパターンをn回繰り返し、「{n,}」ではn回以上、「{n,m}」ではn回以上m回以下を意味する。

グループにまとめる

正規表現をグループ化するには、「(」と「)」でくくる。

例えば「abcを1回以上繰り返した後にdefを1回以上繰り返したもの」という条件は以下のように記述する。

(abc)+(def)+

パターンマッチしたデータの取得

パターンにマッチしたデータはそれぞれ以下の組込変数で取得できる。

$& : マッチデータ
$` : マッチデータ「前」文字列
$' : マッチデータ「後」文字列
data = "123abc789"

data.match(/abc/)

target     = $&
pre_match  = $`
post_match = $'

p "#{target} : #{pre_match} : #{post_match}"

=> "abc : 123 : 789"

また、括弧で条件を指定した場合は以下のような方法でマッチデータを取得できる。

$1 : 1番目の括弧にマッチしたデータ
$2 : 2番目の括弧にマッチしたデータ
$3 : 3番目の括弧にマッチしたデータ

:

$n : n番目の括弧にマッチしたデータ
$+ : 最後の括弧にマッチしたデータ
data = "123abc789"

data.match(/(123)(abc)(789)/)

match1 = $1
match2 = $2
match3 = $3

match_end = $+

p "#{match1} : #{match2} : #{match3} : #{match_end}"

=> "123 : abc : 789 : 789"

応用

case文で正規表現を使う

以下のように通常の正規表現で記述できる。また通常の条件文も混在できる。

case <比較データ>

when /<正規表現>/
  処理

when /<正規表現>/
  処理

when "<通常の条件文>"
  処理

else
  処理

end

例)

case string

when /^type/
  先頭が「type」で始まっている場合の処理

when /^$/
  空行の処理

when "general"
  内容が"general"と一致した時の処理

else
  それ以外の処理

end

これは以下のif文と同義である。

if string =~ /^type/
  先頭が「type」で始まっている場合の処理

elsif string =~ /^$/
  空行の処理

elsif string == "general"
  内容が"general"と一致した時の処理

else
  それ以外の処理

end

URLからホスト/ポート/パスの各要素を取り出す

以下のようにURLを厳密に表現したマッチパターンを使って各要素に分解できる。

url = "http://foo.bar.com:8080/contents"

if url =~ %r!http://(.*?)(?::(\d+))?(/.*)!
  host = $1 if $1 != nil        # ホスト
  port = $2 if $2 != nil        # ポート番号
  path = $3 if $3 != nil        # パス
end

puts host,port,path

=> foo.bar.com
=> 8080
=> /contents

URLからタグを取り除く

「<.*?>」という正規表現を使用すれば簡単にタグが取り除ける。

例)

p '<a href="http://foo.bar.com/">title</a>'.gsub(/<.*?>/, "")

=> "title"

ただしこの方法だと「<データ>」のように通常の文章として書かれている文字列もタグとして取り除かれてしまうので、そのような文字列が文書内に存在する場合は削除対象とすべきパターンを厳密に指定する必要がある。