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だけ

Strutsの生成するスクリプトへの意識も必要で、

以上の縛りあり。

/→[/]
[→[[]
]→[]]

この置き換えで縛りは回避できるけど、]と[は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]))|[;:@&=])*))?)?)$
  • 未対応
    • IPv6省略記法時の桁チェック(厳密化はどこいった?)
    • スコープID
    • URLのフラグメント(RFC1738に無い?)
  • 効率は度外視
  • 無駄な括弧は自作へっぽこ正規表現ジェネレータの仕様

ろくでもないな、、、

これをさらにvalidator.xmlに書くためにXMLエスケープしてわけわかんない状態に

このメモ残すために、はてな記法回避に苦労してるし。もー