IPv4 プライベートアドレスにマッチする正規表現
解説不要な方向け
/^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.0 〜 10.255.255.255
|
172.16.0.0/12 |
172.16.0.0 〜 172.31.255.255
|
192.168.0.0/16 |
192.168.0.0 〜 192.168.255.255
|
上記の範囲内に含まれる 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-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.0.0/8
、172.16.0.0/12
、192.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 アドレスの前後に inet
や brd
などの文字列が入るため、^
と $
は除いています。
-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
であることがわかります。
-
ip
コマンドがあれば (コマンドの実行が失敗しなければ)ip
コマンドを実行し、ip
コマンドがなくてもifconfig
コマンドがあればifconfig
コマンドを実行します。両方ある場合はip
コマンド (先頭に書いたほうのコマンド) が実行されます。 ↩︎
Discussion