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
