参考記事
https://qiita.com/jnchito/items/893c887fbf19e17d3ff9
https://qiita.com/jnchito/items/64c3fdc53766ac6f2008
正直、この記事の執筆者のお世話になりまくりである。なんならこの記事は上の記事のアウトプット記事なので、この記事を読むより良いかもしれない。
正規表現とは
「パターンを指定して、文字列を効率よく検索・置換するためのミニ言語」
と上記の記事に書かれてました。ふむふむ。確かにおぼろげでは、あるが「パターン」や検索,置換には覚えがある。
とりあえずやってみる。みてみる。
正規表現を学ぶためにhttps://rubular.com/ のサイトで遊んでみる。
test string はこんな感じにした。
名前:おにかん
電話:03-1234-5678
住所:東京都中央区1-2-3
\d
と打つと数値のところだけ青く表示された。(ちなみにバックスラッシュはmacならoption+¥でいける)
つまり、\d
は1個の半角数字(0123456789)を表す。\d
はメタ言語とも言い、文字の集合を表すことも意味するので文字クラスとも言うらしい。ふむふむ。
こいつはさっき出てきた「文字列を効率よく検索,置換するためのミニ言語」であり、「パターン」の一つと言うことか。
ともかく、\d
は1個の半角数字を表すと覚えておこう。
メタ文字を繋げてみる。
\d
は1つの半角数字を表すので、2つ、3つを表す場合を学習してみる。
\d\d-\d\d\d\d-\d\d\d\d
と打ってみた。今度はハイフンも含めた全体が選択されている。
\d\d
は二つの連結した半角数字を表す。(12や34みたいな。)
Rubyで動かしてみる
text = <<-TEXT
名前:おにかん
電話:03-1234-5678
住所:東京都中央区1-2-3
TEXT
text.scan /\d\d-\d\d\d\d-\d\d\d\d/
# => ["03-1234-5678"]
ちなみに、text = <<- TEXT
の部分が見慣れていない人は「Ruby ヒアドキュメント」とかで検索すると良いかも。
JavaScriptでも動かしてみる
const text = "名前:おにかん\n電話:03-1234-5678\n住所:東京都中央区1-2-3";
text.match(/\d\d-\d\d\d\d-\d\d\d\d/g);
// => ["03-1234-5678"]
\n
は改行コード。g
はグローバルオプションと呼ばれる。有りと無しでは以下の違いがある。
- あり:最初の一件が見つかったら、検索終了。
- なし:一致する文字列を抽出。
市外局番に対応
/\d\d-\d\d\d\d-\d\d\d\d/
は全ての番号に対応しているわけではありません。例えば、
- 090-1234-5678
- 0120-1234-5678
などなど。これに対応できるような正規表現を学ぶ。ここで大切なことは、検索対象のパターンを見つけること。今回の場合は下記の通り。
- 半角数字の2~5個
- ハイフン
- 半角数字の1~4個
- ハイフン
- 半角数字4個
この順番で並ぶ。ここで出てくる新知識は{n,m} や {n}
というメタ文字を使う。文字量を指定しているので、量指定子と呼ばれる。
{n,m}
は「直前の文字が n 個以上、m 個以下」であることを表す。例えば、\d{1,4}
だったら半角数字で1文字以上4文字以下を表す。
ということで、さっきのパターンに当てはめるとこんな感じになる。
\d{2,5}-\d{1,4}-\d{4}
となるはず。
かっこにも対応したい!
上記のような例では、"03(1234)5678"などに対応できない。なので、ハイフンでも、かっこでも対応できるように変えたい
新しくパターンとして組み込まれるのは「ハイフンまたは(」と「ハイフンまたは)」です。ここで新知識が出てきます。
「AまたはBのいずれか1文字」→[AB]
を意味する。(文字の集合を表すので、文字クラスの一種。)ちなみに、[]
の文字数に制限はない。[ABC]
はどれかの一文字を表す。
ということで、「ハイフンまたは(」は[-(]
。「ハイフンまたは)」[-)]
と表す。では、全体を書いてみる。
\d{2,5}[-(]\d{1,4}[-)]\d{4}
ハイフンは特別な意味を持つことがあります。例えば[A-Z]
は「AまたはBまたはCまたは...Z」を表す。つまり全角の英一文字を表します。つまり、文字の範囲を表すことがあります。
[-AB]
や[AB-]
みたいに[]
の中で最初か最後にハイフンが入るとハイフンそのものとしてとらえられます。
まとめ
-
\d
は半角数字一文字を表す -
{n,m}
は直前の文字がn以上、m文字以下であることを表す。 -
{n}
は、ちょうどn文字を表す。 -
[ab]
aまたはbの一文字 -
[a-z]
は、aまたはbまたはcまたは...zの一文字 -
[-az]
は、-またはaまたはzを表す。
最後に
冒頭でも言いましたが、この記事はアウトプット記事なのでそちらを参考にするといいと思います。