Compnet

仕事とか遊びとか、日々折々

2018-01-12(金)

正規表現を図示してくれる Web サイト

Posted by Nakane, R. in technical   

Note

追記 [2018.1.20]

表題を書き足しました。

また、「{,2}」を「{0,2}」に書き直しました。

Note

追記 [2018.1.15]

正規表現そのものを記載し忘れていたのでこれを書き足しました。

正規表現を書いていると、複雑になってくるにつれてそれが期待通りの表現を示せているのかが、一気に不安になってきます。 そこで正規表現をレールロード ダイアグラム (Railroad Diagram: 鉄道図?) に書き直して確認したりもしますが、これもまた結構面倒な作業です。

最近になって、正規表現をレールロード ダイアグラムに変換してくれる Web サイトの存在を知りました。 この Web サイトを使えば、複雑な正規表現の正しさを多少でも楽に、確認できるようになるのではないかと期待しつつ、備忘録として記録しておきます。

正規表現をレールロード ダイアグラムに変換してくれるのは Regexper という Web サイトです。 英語版しかありませんが、正規表現をレールロード ダイアグラムにして確認するだけであれば、困ることもないでしょう。 ただし、この Regexper では正規表現にスラッシュ (/) をそのままには書けません。 なぜだかエスケープ文字 (\) を前置しないとエラーになるので、その点だけは気をつけなけいといけません。

IPv4 アドレスの正規表現

試しに IPv4 のアドレスを書いてみました。 手始めに、オクテットひとつ分だけを正規表現で示してみます。

0|1([0-9]{0,2})?|2([0-4][0-9]?|5[0-5]?|[6-9])?|[3-9][0-9]?
オリジナルの Regexpr の Web ページはこちら

これをドット (.) で区切って四つならべれば IPv4 アドレスのできあがりです。

(0|1([0-9]{0,2})?|2([0-4][0-9]?|5[0-5]?|[6-9])?|[3-9][0-9]?)(\.(0|1([0-9]{0,2})?|2([0-4][0-9]?|5[0-5]?|[6-9])?|[3-9][0-9]?)){3}
オリジナルの Regexpr の Web ページはこちら

ドット表記のサブネット マスクの正規表現も書いてみました。

((255\.){3}(0|1(28|92)|2(24|4[08]|5[245])))|((255\.){2}(0|1(28|92)|2(24|4[08]|5[24])))\.0|(255\.(0|1(28|92)|2(24|4[08]|5[24])))(\.0){2}|(0|1(28|92)|2(24|4[08]|5[24]))(\.0){3}
オリジナルの Regexpr の Web ページはこちら

ビット数表記も追加した、サブネット付きの IPv4 アドレスの正規表現です。

(0|1([0-9]{0,2})?|2([0-4][0-9]?|5[0-5]?|[6-9])?|[3-9][0-9]?)(\.(0|1([0-9]{0,2})?|2([0-4][0-9]?|5[0-5]?|[6-9])?|[3-9][0-9]?)){3}/(0((\.0){3})?|[12][0-9]?|3[0-2]?|((255\.){3}(0|1(28|92)|2(24|4[08]|5[245])))|((255\.){2}(0|1(28|92)|2(24|4[08]|5[24])))\.0|(255\.(0|1(28|92)|2(24|4[08]|5[24])))(\.0){2}|(1(28|92)|2(24|4[08]|5[24]))(\.0){3})
オリジナルの Regexpr の Web ページはこちら (スラッシュ文字のエスケープに注意)

IPv4 のネットワーク アドレスだと正規表現はこうなります。

(255\.){3}(0|1([0-9]?[02468])?|2(5[0245]?|[024][02468]?|[1379])|[3-9][02468]?)|(255\.){2}(0|1([0-9]?[02468])?|2(5[024]?|[024][02468]?|[1379])|[3-9][02468]?)\.0|255\.{1}(0|1([0-9]?[02468])?|2(5[024]?|[024][02468]?|[1379])|[3-9][02468]?)(\.0){2}|(0|1([0-9]?[02468])?|2(5[024]?|[024][02468]?|[1379])|[3-9][02468]?)(\.0){3}
オリジナルの Regexpr の Web ページはこちら

ただし、サブネット付きの IPv4 のネットワーク アドレスを正規表現で示すのは、不可能とは言いませんが現実的とはいえませんのでここで示すことはしません。

IPv6 アドレスの正規表現

IPv6 アドレスの正規表現です。

([0-9a-fA-F]{1,4}:){7}([0-9a-fA-F]{1,4}|:)|([0-9a-fA-F]{1,4}:){6}:([0-9a-fA-F]{1,4})?|([0-9a-fA-F]{1,4}:){5}((:[0-9a-fA-F]{1,4}){1,2}|:)|([0-9a-fA-F]{1,4}:){4}((:[0-9a-fA-F]{1,4}){1,3}|:)|([0-9a-fA-F]{1,4}:){3}((:[0-9a-fA-F]{1,4}){1,4}|:)|([0-9a-fA-F]{1,4}:){2}((:[0-9a-fA-F]{1,4}){1,5}|:)|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6}|:)|:((:[0-9a-fA-F]{1,4}){1,7}|:)
オリジナルの Regexpr の Web ページはこちら

IPv4 互換アドレスと射影アドレスについては、::::ffff:64:ff9b::2002:: のどれかが IPv4 アドレスの前に付く形なので、正規表現は省略します。 表記の単純化による 0 の連続を省略しない表記まで考慮するならば、正規表現を使う箇所があるかもしれません。 また、2002:: から始まる射影アドレスについてだけは、2002 に続く 80bit の部分がどんな値でもとれるため、正規表現が欲しいと感じることもあるかもしれません。 しかし、そもそも IPv4 互換アドレスや射影アドレスをを使う機会自体がほとんどないでしょうから、やはりここでは省略することにします。

IPv6 のリンク ローカル アドレスではゾーン インデックス (ゾーン ID、スコープ ID とも呼ばれています) が付加されることがありますが、ゾーン インデックスの書式には決まったものがないため、統一的な正規表現では示せません。 強いて正規表現で示すのであれば、以下のようにせざるを得ないでしょう。

%.+
オリジナルの Regexpr の Web ページはこちら

IPv6 のサブネット マスクはビット数表記だけなので、正規表現は以下で示すことができます。

/(0|1([01][0-9]?|2[0-8]?|[3-9])?|[2-9][0-9]?)
オリジナルの Regexpr の Web ページはこちら (スラッシュ文字のエスケープに注意)

確かに正規表現そのままでは分かりにくかったものが、構文図になったことで非常に理解しやすくなります。 欲を言えば、中括弧で示される繰り返し ({...}) の部分がもう少し見やすいといいのですが、贅沢な要望かもしれません。

おまけ

なお、筆者は使っていませんが Atom というテキスト エディターには同じ機能を提供するプラグインがあるみたいです。

Comments