本記事の概要
先日、表題の正規表現が必要になったのですが、人が作った正規表現って理解するまで何だか黒魔術のように思えませんか。
でも、一度成り立ちを理解してしまうとその後はすんなり読むことができる。
そこで、本記事では「文字列を先頭から特定の文字数で二つに分割する」正規表現を組み立てる過程を順を追って解説する。
実現したいこと
文字列の先頭から3文字目までを区切り文字として、文字列を2つに分割し配列で受け取る処理を実現する。
文字列:"foobarbaz"
↓
処理後:["foo", "barbaz"]
解説
1.文字列を分割し配列を返すメソッド
Rubyには文字列を分割して配列を返すsplitメソッドがあるので、これを使う。
※splitメソッドの詳細についてはRuby リファレンスマニュアルをご参照
"foobarbaz".split()
なお、splitメソッドは区切り文字として正規表現を指定できるので、次に正規表現を考えていく。
2.文字列分割のパターン
文字列分割パターンとなる正規表現を考える
# rubyでは、文字列を''で囲むのと同様に正規表現は//で囲む決まりなので、とりあえず//を書く
//
# ↓
# 次に文字列の先頭から文字数をカウントして文字列を分割したいので、「文字列先頭」を意味する\Aを書く
/\A/
# ↓
# 文字を一文字ずつカウントするため、「任意の一文字」を意味する.を書く
/\A./
# ↓
# 次に文字列先頭から3文字カウントしたいので、.を3回繰り返す必要がある
# 正規表現では、繰り返しに{m,n}を使う(最低m回、最大n回)
/\A.{1,3}/
# ↓
# splitメソッドを使うと分割パターンに合致した区切り文字はそのまま削除されてしまう。
# ただし、グルーピングすることでパターンに合致した区切り文字列も処理結果の配列に格納することができる。
# グルーピングは()で囲むことで実現できる。
/\A(.{1,3})/
# ↓
# ここまで作成した正規表現をsplitメソッドの第一引数にする。
# また、今回は文字列を2つに分割したいので、splitの第二引数に2を指定する。
"foobarbaz".split(/\A(.{1,3})/,2)
ここまでで作成した正規表現で文字列分割を実行してみると下記結果となる。
pry(main)> "foobarbaz".split(/\A(.{1,3})/,2)
=> ["", "foo", "barbaz"]
想定通り文字列分割をできてはいるが、配列の最初の要素に空文字が格納されてしまっている。
これは、文字列先頭からが区切り文字となっており、区切り文字より前の文字列がないためである。
配列の最初の要素を除けばいいので、配列の添え字を指定する。
pry(main)> "foobarbaz".split(/\A(.{1,3})/,2)[1..-1]
=> ["foo", "barbaz"]
<補足>
文字列先頭からが区切り文字となると空文字が返される理由がよくわからない人は下記図でイメージをつかんで欲しい。
(例)
【foobarbazをbarを区切り文字に分割した場合】
barを区切り文字として、barの前の「foo」とbarの後ろの「baz」が返されている。
【foobarbazをfooを区切り文字に分割した場合】
fooという区切り文字より前の文字がないため、「空文字」と「barbaz」が返されている。