🕌

IPv4 プライベートアドレスにマッチする正規表現

2021/03/03に公開

解説不要な方向け

/^10\.([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])$|^172\.(1[6-9]|2[0-9]|3[0-1])\.([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])$|^192\.168\.([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])$/

マッチさせたい文字列の前後に任意の文字が含まれていてもマッチさせたい場合は以下のように ^$ を除きます。

/10\.([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])|172\.(1[6-9]|2[0-9]|3[0-1])\.([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])|192\.168\.([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])/

※ 解説不要な場合はここから下は見なくても大丈夫です。

はじめに

IPv4 のプライベート IP アドレスにマッチする正規表現の書き方を紹介します。なお、ここで紹介するのは 10 進数です。

プライベート IP アドレスの範囲

IPv4 のプライベート IP アドレスの範囲は以下の 3 つです。

プレフィックス表記 人間にわかりやすい表記
10.0.0.0/8 10.0.0.010.255.255.255
172.16.0.0/12 172.16.0.0172.31.255.255
192.168.0.0/16 192.168.0.0192.168.255.255

プライベートIPアドレスの範囲

上記の範囲内に含まれる IPv4 アドレスのみにマッチする正規表現です。

正規表現

上記のプライベート IP アドレスの範囲にのみマッチする正規表現は以下の通りです。

/^10\.([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])$|^172\.(1[6-9]|2[0-9]|3[0-1])\.([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])$|^192\.168\.([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])$/

マッチさせたい文字列の前後に任意の文字が含まれていてもマッチさせたい場合は以下のように ^$ を除きます。

/10\.([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])|172\.(1[6-9]|2[0-9]|3[0-1])\.([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])|192\.168\.([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])/

解説

上記の正規表現を分割すると以下の 3 つになります。

10.0.0.0/8に該当
^10\.([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])$
172.16.0.0/12に該当
^172\.(1[6-9]|2[0-9]|3[0-1])\.([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])$
192.168.0.0/16に該当
^192\.168\.([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])$

それぞれ、10.0.0.0/8172.16.0.0/12192.168.0.0/16 の正規表現に該当します。それらを互いに論理和 (|) でつなげています。

0 〜 255 の範囲の表現

([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5]) の部分が 0 〜 255 の数値の範囲を指定しているのですが、もう少し細かく説明すると、以下の 5 つを論理和でつなげています。

  • 0 〜 9 の範囲
  • 10 〜 99 の範囲
  • 100 〜 199 の範囲
  • 200 〜 249 の範囲
  • 250 〜 255 の範囲

このように分けて考えないと、たとえば 001 とか 259 とかにもマッチしてしまうことになります。

また、前後の () はグルーピングです。上記 5 つの範囲指定をひとまとめとして扱うためです。

16 〜 31 の範囲の表現

(1[6-9]|2[0-9]|3[0-1]) は基本的に 0 〜 255 の範囲の表現と同じ書き方です。以下の 3 つを論理和でつなげています。

  • 16 〜 19 の範囲
  • 20 〜 29 の範囲
  • 30 〜 31 の範囲 (30 と 31)

ドットの表現

間のドットは \. です。. は正規表現の記号の一つなので、. という記号自体を表現したい場合は \ でエスケープして \. と表記します。

使用例

ip コマンドや ifconfig コマンドなどでプライベート IP アドレスが設定されているネットワークインターフェース名を調べるときなどに便利です。

$ (ip a 2>/dev/null || ifconfig 2>/dev/null) | grep -E '10\.([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])|172\.(1[6-9]|2[0-9]|3[0-1])\.([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])|192\.168\.([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])' -B 10

Linux では ip コマンド、macOS では ifconfig コマンドを使うので (ip a 2>/dev/null || ifconfig 2>/dev/null) としています[1]

grep の場合は // の代わりに '' で囲みます。また、表示される結果は、プライベート IP アドレスの前後に inetbrd などの文字列が入るため、^$ は除いています。

-E は正規表現を使うオプションです。-B 10 はマッチした行とその上の 10 行も一緒に表示するオプションです。

結果はこんな感じになります。

... (省略)
...
...
...
...
...
...
...
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
    link/ether xx:xx:xx:xx:xx:xx brd ff:ff:ff:ff:ff:ff
    inet 192.168.3.2/24 brd 192.168.3.255 scope global eth0

inet 192.168.3.2/24 brd 192.168.3.255 scope global eth0 の行にマッチして、さらにその上の 10 行も表示されています。

ネットワークインターフェース名が eth0 であることがわかります。

脚注
  1. ip コマンドがあれば (コマンドの実行が失敗しなければ) ip コマンドを実行し、ip コマンドがなくても ifconfig コマンドがあれば ifconfig コマンドを実行します。両方ある場合は ip コマンド (先頭に書いたほうのコマンド) が実行されます。 ↩︎

GitHubで編集を提案

Discussion