IPv6対応URLの正規表現
Struts(というかCommons Validator)がIPv6のURLに対応してないから正規表現で作ることになる。
既存のURLチェック書き換えたほうが早いんじゃ?という意見はなぜか却下。正規表現なら他でも使えるからまあいいかと実装する。
資料はこの辺
- RFC 1738 Uniform Resource Locators
- RFC 2373 IP Version 6 Addressing Architecture
- RFC 2396 URI Generic Syntax
- RFC 2732 Format for Literal IPv6 Addresses in URL's
困ったことにRFCに書いてあるBNFはあまり厳密じゃないから、そのまま正規表現に置き換えでは駄目。特にIPv6がてきとーすぎるので、厳密にしたい。
Webで探したけど大抵BNFそのまま正規表現だし、人の作った正規表現のメンテは大変なので自作する。
条件
- java.net.URLのコンストラクタと同レベルのチェック
- OROのPerl5とJavaScript両方で使える
- スキームはhttpとhttpsだけ
以上の縛りあり。
/→[/] [→[[] ]→[]]
この置き換えで縛りは回避できるけど、]と[はjava.text.Patternでは使えない書式。互換にしたかったけどしょうがない
というわけで作った正規表現
^(https?:[/][/]((((([0-9a-zA-Z]|[0-9a-zA-Z]([0-9a-zA-Z]|-)*[0-9a-zA-Z])[.])*([a-zA-Z]|[a-zA-Z]([0-9a-zA-Z]|-)*[0-9a-zA-Z]))|([0-9]{1,3}[.][0-9]{1,3}[.][0-9]{1,3}[.][0-9]{1,3})|([[]((([0-9a-fA-F]{1,4})(:([0-9a-fA-F]{1,4})){7})|((([0-9a-fA-F]{1,4})(:([0-9a-fA-F]{1,4})){5}):([0-9]{1,3}[.][0-9]{1,3}[.][0-9]{1,3}[.][0-9]{1,3}))|(((([0-9a-fA-F]{1,4})(:([0-9a-fA-F]{1,4}))*)::((([0-9a-fA-F]{1,4})(:([0-9a-fA-F]{1,4}))*))?|::((([0-9a-fA-F]{1,4})(:([0-9a-fA-F]{1,4}))*))?)(:([0-9]{1,3}[.][0-9]{1,3}[.][0-9]{1,3}[.][0-9]{1,3}))?)|::([0-9]{1,3}[.][0-9]{1,3}[.][0-9]{1,3}[.][0-9]{1,3}))[]]))(:([0-9]{1,5}))?)([/]((((([a-zA-Z]|[0-9]|[-$_.+]|[!*'(),])|(%[0-9a-fA-F][0-9a-fA-F]))|[;:@&=])*)([/](((([a-zA-Z]|[0-9]|[-$_.+]|[!*'(),])|(%[0-9a-fA-F][0-9a-fA-F]))|[;:@&=])*))*)([?](((([a-zA-Z]|[0-9]|[-$_.+]|[!*'(),])|(%[0-9a-fA-F][0-9a-fA-F]))|[;:@&=])*))?)?)$
ろくでもないな、、、
これをさらにvalidator.xmlに書くためにXMLエスケープしてわけわかんない状態に
このメモ残すために、はてな記法回避に苦労してるし。もー