ねりあずぶろぐ

雑多です。

コータス先生の正規表現講座

とある日のクチートちゃんとコータス先生の会話

f:id:nerianighthawk:20170705205354p:plain(クチートちゃん)「コータス先生、こんにちは!」

f:id:nerianighthawk:20170705210126p:plain(コータス先生)「こんにちは、今日はどうしたんだい?」

f:id:nerianighthawk:20170705205354p:plain「はい、早速本題ですが正規表現ワイルドカードの違いがどうしてもわからなくて…。」

f:id:nerianighthawk:20170705210126p:plain「なるほど、たしかにごっちゃにしている人は多いねぇ…。ちなみにクチートくんの認識はどうなんだい?」

f:id:nerianighthawk:20170705205354p:plain「えっと、ワイルドカード正規表現も文字列の検索に使うものですよね?ワイルドカードの方が表現力が少ないなぁって感じる程度ですね。」

f:id:nerianighthawk:20170705210126p:plain「うん、まあ間違ってはないけど、その認識だと違いはわかりづらいかもなぁ。でも表現力っていうのは一つの違いだと思ってくれていいかな。文字列検索で使えるものというのも間違ってはいないから、文字列検索をする上での使用感の違いから入る方がいいかもね。」

f:id:nerianighthawk:20170705205354p:plain「でもひとくくりに正規表現と言っても実際はいくつも種類がありますよね?だったらワイルドカードも表現力の低い正規表現ってことになりませんか?」

f:id:nerianighthawk:20170705210126p:plain「あー、その認識はまずいね。なぜなら正規表現ワイルドカードでは文字列の検索の仕方が根本的に違うからね。」

f:id:nerianighthawk:20170705205354p:plain「説明をお願いします!」

f:id:nerianighthawk:20170705210126p:plain「そうだねぇ、例えば下の2つは同じように文字列検索をできるよね?」

ワイルドカード:あい*えお
正規表現   :あい.*えお

f:id:nerianighthawk:20170705205354p:plain「そうですね、どちらも"あい"の後に任意の文字が0文字以上続いて"えお"ってなっている文字列を検索します。」

f:id:nerianighthawk:20170705210126p:plain「そうだね、でもクチートくんの言った考え方はワイルドカード寄りの考え方なんだ。ワイルドカードでは、任意の文字を表す記号(だいたいは"*“と”?“)を扱って文字列検索を行うよ。」

f:id:nerianighthawk:20170705205354p:plain「え、じゃあ正規表現だとどういう考え方なんですか?」

f:id:nerianighthawk:20170705210126p:plain正規表現だと、『"あい"と"えお"の間に任意の文字が0文字以上続くような文字列の集合の中に存在する文字列を検索する』と考えるよ。」

f:id:nerianighthawk:20170705205354p:plain「そういえば、正規表現は文字列の集合を1つの文字列で表現したものだっていうのをどこかで読みましたね…。いまいちピンと来てないんですが、もう少し砕いた説明はありませんか?」

f:id:nerianighthawk:20170705210126p:plain「そうだね、いきなり文字列の集合だとか言われてもよくわかんないよね。じゃあまず簡単に0~9上での正規表現を考えてみようか。」

f:id:nerianighthawk:20170705205354p:plain「0~9上での正規表現???」

f:id:nerianighthawk:20170705210126p:plain「そう、文字としては{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}(以下この集合をNとおく)の10個の文字だけを使った正規表現だよ。」

f:id:nerianighthawk:20170705205354p:plain「なるほど、実用性は低そうですが、理解する上では重要なんでしょうね。」

f:id:nerianighthawk:20170705210126p:plain「デデン!それでは問題です!」

f:id:nerianighthawk:20170705205354p:plain(突然なんか始まった…)

f:id:nerianighthawk:20170705210126p:plain正規表現は文字列の集合です。では、N上の正規表現"..“はどんな集合でしょう?」

f:id:nerianighthawk:20170705205354p:plain「えっと、".“が任意の1文字を表す正規表現で今は0~9の文字しか使えないから…。答えは{00, 01, 02, …, 99}です!」

f:id:nerianighthawk:20170705210126p:plain「正解!正解したあなたにはどくけしをプレゼント!」

f:id:nerianighthawk:20170705205354p:plain(私、毒無効なんだけどなぁ…)

f:id:nerianighthawk:20170705210126p:plain「第2問!N上の正規表現で"0*“はどんな集合でしょう?」

f:id:nerianighthawk:20170705205354p:plain「2問目あるんですか!えっと、"*“は直前の文字が0文字以上続くの意味なので、答えは{0, 00, 000, 0000, …, 00000, …}ってあれ?無限集合になってしまいました…。」

f:id:nerianighthawk:20170705210126p:plain「残念、不正解!でも無限集合になってしまったからではないよ、むしろ無限集合になることは構わないよ。ちなみに正解は{, 0, 00, 000, 0000, …, 00000, …}。空の文字を忘れているよ。」

f:id:nerianighthawk:20170705205354p:plain「あ、そうか。0文字以上だから空の文字を含めなくちゃいけないんですね!」

f:id:nerianighthawk:20170705210126p:plain「どうだろう?少しは正規表現をわかってもらえたかな?」

f:id:nerianighthawk:20170705205354p:plain「そうですね、今になって考えるとワイルドカード正規表現って全然違うものなんだなと感じます。」

f:id:nerianighthawk:20170705210126p:plain「それはよかった。厳密に定義しようとするともう少し数学に詳しくないといけないから、その話はまた今度だね。」

f:id:nerianighthawk:20170705205354p:plain「はーい!今日はありがとうございました!」

まとめ

ワイルドカード:任意の文字を表す記号を使う。語源はトランプのワイルドカード(どんなカードにでもなれるカード)から来ているので、同じようなものだと考えて良い。 正規表現:文字列の集合を一つの文字列で表現する表現方法。何かしらの文字の集合が用意されており、その上に定義される。文字列検索の際はその集合の元として存在するかどうかで検索する。