Rubyで正規表現を使う方法です。
正規表現(regular expression)は、文字列のパターンを表現する仕組みです。
Step1. 正規表現の表現
/
で囲まれた部分、もしくは%r{}
の内側が正規表現となります。
/正規表現/ %r{正規表現}
正規表現は、文字列そのもののリテラル
と、パターンを記述するメタ文字
があります。
次の例の場合、「appleもしくはgrape」と読み、apple
とgrape
がリテラルで、|
がメタ文字です。
/apple|grape/
Step2. 正規表現の使いどころ
正規表現は、文字列クラスのmatch
, gsub
メソッドなどと一緒に使ったりします。
match
文字列str
に対して、正規表現に一致する部分を探して、一致した箇所を抽出します。結果は配列で返ります。正規表現にカッコ()
がある場合は、1つめのカッコは配列[1]
に、2つめのカッコは配列[2]
に格納されます。
一致した部分 = str.match(正規表現)
gsub
文字列str
に対して、正規表現に一致する部分を探して、一致した箇所を指定の文字列に置き換えます。
置換した文字列 = str.gsub(正規表現, 置換する文字列)
Step3. 正規表現の使い方
次の文字列hello world
に対して、正規表現を使っていきます。動作確認はコンソールを使っています。
str = "hello world"
特定の文字列を抽出するには、単純にその文字列を書きます。文字列hello
を抽出してみます。
r = str.match(/hello/)
=> #<MatchData "hello">
任意の1文字を指定するには、.
を使います。文字列hello
を抽出してみます。
# 3文字目は、任意の1文字。
r = str.match(/he.lo/)
=> #<MatchData "hello">
いずれかの文字を指定するには、[いずれかの文字]
のように[]
内にマッチさせたい文字を指定します。文字列hello
を抽出してみます。
# 3文字目はk, l, mのいずれか。
r = str.match(/he[klm]lo/)
=> #<MatchData "hello">
いずれかの文字を範囲で指定するには、[開始文字-終了文字]
のように[]
内に-
で範囲を指定します。文字列hello
を抽出してみます。
# 3文字目はa〜zのいずれか。
r = str.match(/he[a-z]lo/)
=> #<MatchData "hello">
いずれかの文字以外を指定するには、[^除外する文字]
のように[]
内に^
で除外する文字を指定します。文字列hello
を抽出してみます。
# 3文字目はa,b,c以外。
r = str.match(/he[^abc]lo/)
=> #<MatchData "hello">
いずれかの文字を表す方法として、次の省略記法
が用意されています。
\w
単語構成文字 [a-zA-Z0-9_]\W
非単語構成文字 [^a-zA-Z0-9_]\s
空白文字 [ \t\r\n\f\v]\S
非空白文字 [^ \t\r\n\f\v]\d
10進数字 [0-9]\D
非10進数字 [^0-9]\h
16進数字 [0-9a-fA-F]\H
非16進数字 [^0-9a-fA-F]
省略記法
の\w
を使って、文字列hello
を抽出してみます。
# 3文字目は単語構成文字のいずれか。
r = str.match(/he\wlo/)
=> #<MatchData "hello">
繰り返しを表現する方法は何種類か用意されています。
*
0回以上 (0回とは一致するものが無い状態)+
1回以上?
0回もしくは1回{n}
ちょうどn回(nは数字){n,}
n回以上(nは数字){,m}
m回以下(mは数字){n,m}
n回以上m回以下(n,mは数字)
繰り返しの+
を使って、文字列hello
を抽出してみます。
# 単語構成文字が連続している部分を抽出する。
r = str.match(/\w+/)
=> #<MatchData "hello">
Step4. 正規表現の練習 match
URL文字列の http://example.com/id=12ab/
からid番号の12ab
を抽出してみます。
初めに、URL文字列は/
を含んでいるので、Regexp.escape
メソッドでエスケープします。
str = Regexp.escape("http://example.com/id=12ab/")
id番号は文字列id=
と/
に挟まれた部分を抽出すればよいようです。id=
の後ろの単語構成文字(\w
)が連続(+
)している部分を抽出します。
r = str.match(/id=\w+/)
=> #<MatchData "id=12ab">
抽出できましたが、不要な文字列"id="
が頭についていますので、抽出したい部分(\w+
)を括弧()
で括ります。
r = str.match(/id=(\w+)/)
=> #<MatchData "id=12ab" 1:"12ab">
戻り値[0]
に"id=12ab"
が格納され、戻り値[1]
に"12ab"
が格納されました。結果を確認してみます。
r[0] => "id=12ab" r[1] => "12ab" r[2] => nil
id番号が抽出できました。
Step5. 正規表現の練習 gsub
URL文字列の http://example.com/id=12ab/
のid番号12ab
をcc12ab
に置換してみます。
初めに、URL文字列は/
を含んでいるので、Regexp.escape
メソッドでエスケープします。
str = Regexp.escape("http://example.com/id=12ab/")
id番号は文字列id=
と/
に挟まれた文字(\w+
)部分を抽出します。ここでid番号は元の値を残して置きたいので括弧()
で括ります。
gsub
の第二引数には置換する文字列を指定します。第一引数で括弧で括った箇所は、置換文字列の中で\1
とすると使えます。括弧がいくつもある場合は、\1
, \2
, …, \9
と順に割り当てられます。
r = str.gsub(/id=(\w+)/, 'id=cc\1')
=> "http://example\\.com/id=cc12ab/"
置き換えられました。