IPアドレスの正規表現はどう書いたらよいか調べてみた。Rubyで使用することを想定している。
ここの記事に書いてあるのが良さそうなので採用することにした。
How to Match IPv4 Addresses with Regular Expressions – O’Reilly Answers
^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$
これまで簡単な正規表現しか使ってこなかったので、最初見たときよくわからなかった。。。
まず、?:
て何よ。記号だけの記述をGoogleで検索するのってむずかしいんだな。
なんとか、丁寧に解説されていたPerlの正規表現の解説記事を見つけた。
(?:…)
後方参照を行わないグループ化\1 や \2 を使用した後方参照が出来ません。
なるほど、( )
でグループ化はできるけど後方参照もしてしまうけど、IPアドレスの第1オクテットの数だけあとから取り出したいと言うケースはあまりないのではないかと思うので、グループ化しない書き方になっているわけだ。
25[0-5]
が250-255、2[0-4][0-9]
が200-249、[01]?[0-9][0-9]?
が0-99の範囲を表している。
0-255と. (\.
)で構成されたものが3回繰り返し ({3}
)して最後も0-255の数字となる。
これで0.0.0.0から255.255.255.255までのIPアドレスを表現している。もちろん、そのIPアドレスがブロードキャストアドレスだとかプライベートアドレスだとかいうことは関係ない。
pry> reg = /^((?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?))$/ => /^((?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?))$/ pry> reg =~ '0.0.0.0' => 0 pry> reg =~ '192.168.1.1' => 0 pry> reg =~ '255.255.255.255' => 0 pry> reg =~ '300.1.1.1' => nil
ちなみに、1桁の数字の場合で前に0が入っていてもマッチする。
pry> reg =~ '192.168.001.001' => 0 pry> reg =~ '192.168.01.01' => 0
文字列全体を検証したい場合はこれでOKですが、文章中のIPアドレスにマッチさせたい場合は、^, $
の代わりに文字区切り\b
を前後に入れるとよい。
/\b(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\b/
後方参照したい場合は外側を( )
で囲む。
/\b((?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?))\b/
マッチしたIPアドレスの文字列を$1で参照することができる。
ptr> reg = /\b((?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?))\b/ => /\b((?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?))\b/ pry> reg =~ '172.165.10.24 - - [16/Jun/2013:12:55:59 +0900]' => 0 pry> $1 => "172.165.10.24"
まとめ
文字列がIPアドレスかどうかを検証する場合
/^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/
文章中にIPアドレスが含まれるか検証する場合
/\b(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\b/
文章中のIPアドレスにマッチして後方参照でマッチしたIPアドレスを使用する場合
/\b((?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?))\b/
こうした方がいいとか、間違っているとかありましたら教えて下さいませ。
関連記事
- None Found