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]\d10進数字 [0-9]\D非10進数字 [^0-9]\h16進数字 [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/"
置き換えられました。