
正規表現の存在を知り、いつかは使えるようになりたいと思ったあの日から早2年、そろそろ正規表現を使えるようになります。
ということで、今回は正規表現をレベルごとにスッテプバイステップでまとめていきます。
- 正規表現とは?
- Step1:何でも良い一文字.
- Step2:文字列の終わりと始まり^ $
- Step3:文字の繰り返し* ? +
- Step4:条件付け|
- Step5:指定した文字や数字のどれか[]
- まとめ
- 参考
Rを使っている方は{stringr}パッケージのstr_view関数を使って、str_view(文字列ベクトル,パターン)とするとマッチする箇所が確認できるので正規表現の練習におすすめです!
正規表現とは?
そもそも、正規表現とは文字列を一つの文字列で表現する方法です。例えば、複数の単語の中からaで始まる単語や、gで終わる単語、数字を含む単語など任意の条件にマッチした文字列を探し出すことができます。
また、「あの単語なんだっけ?ほらaだったかbだったかで始まって、最後に"g"で終わるやつ、あれ?fだっかな?数字も混じっていたような....」みたいな、曖昧な記憶にも対応できてしまいます。
さて、そろそろ始めましょうか。
Step1:何でも良い一文字.
まずは、一文字だけが分からない場合に使うのが.です。.は文字でも数字でもなんでもいい一文字を表現できます。(注:文字列は適当です)
p.n
- pan
- pen
- pon
- pin
.a.
- Aan
- dan
こんな感じになります。
ちなみに.自体を文字として表したい場合は、バックスラッシュ\をつけると.を文字として表すことができます。(ちなみにRを使っている方はバックスラッシュを2つつけて、\\.とする必要があります。)
hog.\.csv
- hoga.csv
- hogu.csv
- hoge.csv
一つ目の.はなんでも良い一文字を表し、二つ目の.はバックスラッシュが付いているため文字としての.を表しています。
Step2:文字列の終わりと始まり^ $
お次のステップは分かりやすいかと思います。〜で始まる文字列は^、〜で終わる文字列は$で表します。
例えばaで始まる文字列を表す時には^aと表し、zで終わる文字列を表す時はz$とします。
Step3:文字の繰り返し* ? +
文字の繰り返しを表現するのがこの三文字です。ここが正規表現を学ぶ際の第一の関門です。
ややこしいですが
?:前の文字が0回か1回繰り返す+:前の文字が1回以上繰り返す*:前の文字が0回以上繰り返す
という意味になります。
具体的にいきましょう。
Apple?
- Apple
- Appl
?は前の文字が0回か1回繰り返すことを表すので、?の前のeが1個あるAppleとeがないApplがマッチします。
Apple+
- Apple
- Appleeeee
+は前の文字が1回以上繰り返すことを表すので、eがないApplはマッチしません。その代わりeが何個繰り返してもマッチします。
Apple*
- Appl
- Apple
- Appleeeeee
*は前の文字が0回以上繰り返すことを表すので、eがないApplもeが何個も繰り返すAppleeeeeeもマッチします。*が一番緩い条件ですね。
また、{}を使うことで、明示的に繰り返し数を指定することができます。
a{2}:2回繰り返しaaのみa{2,}:2回以上繰り返しaaa,aaaaaなどa{2,3}:2回から3回まで繰り返しaa,aaaのみ
さらに先ほどの.や^、$を組み合わせることで、文字列検索の幅が一気に広がります。
例えば、^A.*e$とすると、.*は何でも良い文字の0回以上の繰り返しを表すため、Aで始まり、eで終わる全ての文字列にマッチします。
^A.*e$
- Apple
- Ae
- AppleOrangeGrape
Step4:条件付け|
今度はaかbのどっちかにマッチさせたい時には、その条件を|で指定できます。
p(a|i)n
- pan
- pin
pとnの間には、aまたはiが指定されているので、マッチするのは上の二つだけになります。
さて、ここまでで「あの単語なんだっけ?ほらaだったかbだったかで始まって、最後に"g"で終わるやつ、あれ?fだっかな?」に対応することができます。
これを表すには、Step1~4までを総動員して
^(a|b).*(g|f)$
と表します。
ここまでくればもう一息、「数字も混じっていたような....」にも対応できるようになりましょう!
Step5:指定した文字や数字のどれか[]
[]は条件付けをさらに拡張したものだと思ってください。例えばAからZまでのどれかや1から5までのどれかなど文字や数字を範囲で指定できます。
windows[7-9]
- windows7
- windows8
- windows9
[A-D]型
- A型
- B型
- C型
- D型
また先ほどは先頭文字を表した^ですが、[]の中で使うと否定の意味になり、指定した文字範囲以外でという意味になります。
windows[^6-8]
- windows5
- windows9
- windows10
これで「数字も混じっていたような....」にも対応できるようになりました。
これを表すには数字のどれかが0回以上繰り返せば良いので、
^(a|b).*[0-9]*(g|f)$
とします。これでaまたはbで始まり、数字を含んでいる可能性があり、gまたはfで終わる単語を表すことができるようになりました。(そんな単語あるのでしょうか...)
まとめ
今回はなかなか理解が進まなかった正規表現についてまとめてみました。 実は正規表現はこんなもんじゃないんですが、一気にやるとやる気がなくなってくるので、少しづつ使えるパターンを増やしていくのがいいですね。