結論から言うと「なんで君そんな質問するの?」ってくらい違うんですが、最初見た時挙動がイメージできなかったのと、特殊文字のせいでググっても全然ヒットしなかったこともあって記事にしておきます。
#事の発端
最近Djangoの開発案件にアサインされたのでソースコード見ながら勉強していたんですが、Railsで言うところのルータであるurls.py
(ルートURLconf)にこんな感じでルーティングが定義されていました。
(...)
urlpatterns = [
url(r'^$', views.hoge),
url(r'', include(fuga)),
(...)
]
(...)
1行目はわかるんですよ。パス指定なしでルートディレクトリにアクセスした時のルートなんだな~と。
2行目はなんですか・・・。空文字・・・? ルートディレクトリの後に空文字だから、1行目と同じでは・・・???
頑張ってGoogleで「urlpatterns 空文字」とか調べてみたんですが、それらしい解説には出会えず・・・。
#解決編
困り果てて社用Slackで「わからん~!」と喚いていたら、優しい先輩方が助けてくれました。
空文字にマッチするr''
という正規表現は、どうやらすべての文字列にマッチするワイルドカード的な書き方のようです。
そう言われて「なるほど」と思い、自分でも検証してみると、
import re
if(re.match(r'', "abcde")):
print("match") # -> "match"
if(re.match(r'', " ")):
print("match") # -> "match"
確かに、何にでもマッチしています。
つまり、上のurlpatterns
の書き方は、「ルートディレクトリ以外へのアクセスはとにかく全部include(fuga)
してね」という意味だったんですね。いやはや勉強になりました。
#もうちょっと詳しく
とりあえず当初の疑問は解消したわけですが、どうにもモヤモヤします。というのも、検証している過程で
import re
m = re.findall(r'', "abcde")
print(m) # -> ['', '', '', '', '', '']
・・・どゆこと? という疑問が生じたためです。
再び考え込んでいるうちに、「正規表現はオートマトン」ということを思い出しました。オートマトンについてはまだ人にちゃんと説明できるほど勉強できていないんですが、ざっくり言うと「入力によって状態が遷移する機構(なんともそれっぽい)」だと思ってます。
つまり、r''
という正規表現は、「「何も入力がない1」が入力されたら「マッチした」という状態に遷移するオートマトン」を意味していたわけです。
(お粗末な図で恐縮です)
なので、文字列abcde
をr''
で判定する際には、行頭・文字と文字の間・行末において「何も入力がない」が発生するため、m
の長さは6になったというわけです。
先輩が「r'.*'
は最後まで読み込まないといけないけど、r''
は1文字も読み込まなくてもマッチするから速い」と言っていた意味も半分理解できました(もう半分は最長一致がどうとかいう話だと思いますが、おいおい勉強しようと思います)。
#まとめ
正規表現のグーグラビリティの低さには困ったものですね・・・。
#参考文献
『オートマトン 言語理論 計算論 I [第2版]』サイエンス社 2003年
-
オートマトンではこれを
ε
で表すらしいです。 ↩