正規表現を苦手としている方は少なくないと思います。
ただ、正規表現に関しては基礎的な部分だけおさえておけば大きな問題はないと思うので、ここで理解を深めてしまいましょう!
ある程度自信のある人は一番最後の例題を見てパッと理解できるか確認してみてください。
正規表現とは
正規表現とは、文字列のパターンを表したものです。
正規表現は/ /
で囲んで記述します。
正規表現の基礎項目
正規表現を扱う上で必要な基礎項目を列挙していきます。
=~
正規表現と文字列がマッチするかをどうかを調べるためのメソッドです。
正規表現 =~ 文字列
マッチする場合、文字の位置を返し、マッチしない場合、nilを返します。
puts /a/ =~ "dance"
# 1
^ $ \A \z
^は行頭にマッチ
$は行末にマッチ
\Aは文字列の先頭にマッチ
\zは文字列の末尾にマッチ
[ ]
いくつかの文字のうちその1つを指定したい場合は[ ]
で囲む。
/[abc]/
# aかbかc
/[a-z]/
# a~z
/[^abc]/
# abc以外の文字
※単なる文字として-を表したい場合は[ ]内の最後に記述します。
.
.(ドット)はどんな文字にもマッチする。
/aaa.../ =~ "000aaabcdef"
# aaabcdがマッチ
\を使った記法
\s 空白文字を表す
\S 非空白文字
\d 0~9までの数字にマッチ
\w 英数字にマッチ
\A 文字列の先頭にマッチ
\z 文字列の末尾にマッチ
また、メタ文字を普通の文字として使うときは\
をつける。
例えば、[
に対しては\[
とする。
繰り返し
* 0回以上の繰り返し
+ 1回以上の繰り返し
? 0回か1回
{n} n回の繰り返し
{n,m} n~m回の繰り返し
「0回以上の繰り返し」の意味が最初はよくわからないかもしれませんが、「直前の文字が1回以上繰り返されているか、なくてもいい」と考えると理解しやすいです。
{n}
に関しては5回以上なら{5,}
5回以下なら{,5}
5~10回なら{5,10}
とかけます。
最短マッチ
*? 0回以上の繰り返しのうち最短の部分
+? 1回以上の繰り返しのうち最短の部分
*や+は、可能な限り長い部分にマッチさせます。
*?や+?とすると最短部分にマッチするようになります。
string = "abcdabcdabcd"
/a.*b/ =~ string
# "abcdabcdab"がマッチ
string = "abcdabcdabcd"
/a.*?b/ =~ string
# "ab"がマッチ
i オプション
iをつけると、アルファベットの大文字小文字の違いを無視する。(どちらでもマッチする)
string = "abcdABCDabcd"
/a.*b/i =~ string
# "abcdABCDab"がマッチ
キャプチャ
正規表現を使ってマッチした部分を色々と操作することができます。
ここをおさえられると実用性がグッと高まります。
マッチした結果を保持する変数
$` マッチした部分より前の文字列
$& マッチした部分の文字列
$' マッチした部分より後ろの文字列
string = "abcdef"
/c./ =~ string
p $`
# "ab"
p $&
# "cd"
p $'
# "ef"
また、正規表現を( )で括った部分を$1
で取ることができます。
string = "abcdef"
/(.c)/ =~ string
p $1
# "bc"
正規表現内で( )が複数つけた場合は順に$2、$3でマッチした部分を取ることができます。
gsubメソッド
マッチした文字列を別の文字列に置き換えるメソッド。
string = "a b c d e"
p string.gsub(/\s+/, " ")
# "a b c d e"
ブロックを渡すこともできる。
string = "abcabcabc"
string.gsub(/.c/) do |matched|
p matched
end
# bc
# bc
# bc
ちなみにsubメソッド
は最初にマッチした部分だけを置き換えます。
scanメソッド
マッチした部分を取り出す。
置換をしないのであればこっちを使えばいい。
string = "abcabcabc"
string.scan(/.c/) do |matched|
p matched
end
# bc
# bc
# bc
例題
ここまでで基本はいいと思います。
例題をいくつか見てみましょう。
例1
問:emailのドメイン部分を抜き出す。
email = "hogefuga@gmail.com"
/\A\S+@(\S+)\z/ =~ email
p $1
# "gmail.com"
例2
問:「正規表現は難しい!」を「正規表現は楽しい!」に変更する。
string = "正規表現は難しい!"
p string.gsub(/難しい/, "楽しい")
# "正規表現は楽しい!"
ちなみに、複数の変更をすることもできます。
「正規表現は難しい!無理だ!」を「正規表現は楽しい!ヤッホー!」に変更する。
string = "正規表現は難しい! 無理だ!"
p string.gsub(/難しい|無理だ/, "難しい" => "楽しい", "無理だ" => "ヤッホー")
例3
問:"my-name-is-taro"を"My-Name-Is-Taro"のように変換できるメソッドを作る。
def word_capitalize(string)
string.gsub(/[a-z]+/, &:capitalize)
end
p word_capitalize("my-name-is-taro")
例1〜3は、他にもやり方があると思いますので色々試してみてください。
まとめ
正規表現の基本について確認をしました。
rubyの正規表現ですが、例えばJavaScriptでもほとんど同じような形で使えるので、基本をおさえておくと実装の幅が広がるかと思います。
今回は以上です!