質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

正規表現

正規表現とは特定の文字列によるパターンマッチングを行う際に用いられる宣言型プログラミングです。

Q&A

解決済

3回答

14509閲覧

IPアドレスの正規表現について

poponta

総合スコア12

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

正規表現

正規表現とは特定の文字列によるパターンマッチングを行う際に用いられる宣言型プログラミングです。

0グッド

0クリップ

投稿2017/03/27 08:18

###前提・実現したいこと

Javascriptにてシステムを作成しています。

IPアドレス入力のバリデーションにおいて、
正規化表現を利用しようと思っています。

X.X.X.Xだけの正規表現は検索して解決しましたが、
X.X.X.X/Yのようなサブネットを含む表現は解決できていません。

どのように表記すればよろしいでしょうか?

X.X.X.X~Z.Z.Z.Zという範囲を求めるのではなく、
X.X.X.X/Yという入力表記が正しいかどうかを判断したいです。

###試したこと

X.X.X.Xなら
/^(([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]).){3}([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$/
でいけました。

お手数をおかけしますが、ご回答お願いいたします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

ikedas

2017/03/27 08:27

他の手段ではなく正規表現を利用する理由は何ですか。
poponta

2017/03/27 08:30

正確に言うとExtJSでプログラムを組んでいて、入力時のバリデーションが正規表現で実現できるためです、
guest

回答3

0

ベストアンサー

IPv4 アドレスの表記で aaa.bbb.ccc.ddd/zz の /zz の部分は「ネットワークアドレスのビット長」を指しているので、zz が 0~32 の間の数値であれば問題がありません。
例えば 192.168.0.2/24 という表記は全くもって正しいです(これだとサブネットマスクが 255.255.255.0 であるネットワークであることを明示しているだけ)。

ですから、上の条件に合致するだけであれば、今の IP アドレスの正規表現に加えて、末尾に (/([0-9]|[1-2][0-9]|3[0-2])){0,1} を加えるだけでよいはずです。
※/ で始まり、0~32 の数値が続く文字列が、0ないし1回出現する

192.168.0.0/24 という表記は CIDR といって、厳密には違います。こちらだと 192.168.0.0 ~ 192.168.0.255 という「ネットワークアドレスの範囲」を示していると取られます。(どちらを意味しているかは文脈で判断するしかない)
これに合致しているかどうかということになると、正規表現でやらない方がよいでしょう。

投稿2017/03/27 08:36

tacsheaven

総合スコア13703

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

poponta

2017/03/27 23:54

ご回答ありがとうございました。 教えていただいた表現でうまくいきました。 助かりました。
guest

0

IPアドレスは一桁や二桁の数値の場合0で頭を埋めるケースもあるので
なにをもって正しいとするか定義されていないと意味がない質問です。
また直接0が入ることも想定したほうがよいです

たとえばこんな感じで抜き出した上で数値の整合性をチェックしたほうがよいかも

var str="10.1.2.3"; var reg=new RegExp("^([0-9]+)\.([0-9]+)\.([0-9]+)\.([0-9]+)$"); console.log(str.match(reg).filter(function(i,j){return (j>0 && i>=0 && i<=255);}).length==4);

投稿2017/03/27 12:01

編集2017/03/27 12:10
yambejp

総合スコア114779

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

think49

2017/03/28 06:59 編集

> IPアドレスは一桁や二桁の数値の場合0で頭を埋めるケースもあるので これは何の規約による定義でしょうか。 RFC3986 では IPv4address において「010.001.002.003」は許可されないと文法が定められていました。 https://triple-underscore.github.io/RFC3986-ja.html#section-3.2.2
yambejp

2017/03/28 07:15

「10.001.002.003」は参照の際には有効です また十進に換算して「167838211」でも参照できます。 だから・・ 「なにをもって正しいとするか定義されていないと意味がない」のです。
tacsheaven

2017/03/28 07:32 編集

RFC3986 の規定は、URI を記述する際に Host として IPv4 アドレスを記載する際のフォーマットであって、IPv4 アドレスの記載法全てに影響するものではありませんね。 実際、gethostbyname() が受け付ける表記(=inet_aton() が受け付ける表記)は、https://linuxjm.osdn.jp/html/LDP_man-pages/man3/inet_addr.3.html を見てもわかるように、拡張されています。
think49

2017/03/28 08:21 編集

To: yambejp さん > 「10.001.002.003」は参照の際には有効です 「参照する場合」は何のアプリケーションで参照する事を意図しているのでしょうか。 Google Chrome においてアドレスバーで http://010.001.002.003/ を叩いた場合、http://8.1.2.3/ に変換してページ遷移を試みる動作になりました。どうやら「0パディングされた数値」を8進数と解釈するようです。 また、「192.168.100.*/24」のIP体系の Windows 10 PC のコマンドプロンプトにおいて「ping 192.168.100.030」を叩いたところ、 「192.168.100.24」にping送信する挙動となりました。コマンドプロンプトも0を詰めた8進数と解釈しているようです。 これらの結果から「0パディングされたIPアドレス」はRFC違反(不正なIPアドレス)ですが、アプリケーションによっては「8進数であらわしたIPv4アドレス」と認識して「10進数のIPv4アドレス」と解釈する動作となる、と判断できます。 > 「なにをもって正しいとするか定義されていないと意味がない」のです。 これは「RFC3986」が一つの答えになると考えていました。 0パディングしたIPアドレスが8進数として解釈する動作がどこかで仕様化されているなら、読んでみたところですが、標準化されているのでしょうか。 To: tacsheaven さん Linuxの関数を表しているようですが、アプリケーションレベルの話ではなくて標準仕様としての「正しいIPv4アドレス」を求めているものと認識していました。 「0パディングされたIPv4アドレス」には標準化された仕様があるのでしょうか。
tacsheaven

2017/03/28 08:31 編集

>think49 さん 0パディング表記は RFC に規定がありません。ただし、大元の RFC952 では単に digit (#)としか記述しておらず、RFC3986 のように厳密な定義がなされていませんから、「数値として解釈できるなら何でもあり」としても間違いではありません。 そして C では 0 プレフィックスされて0-7までの数字しか使われていないならば 8 進数の数値定数として扱うという仕様があるので、結果として8進数として解釈される実装が存在している(そしてそれが事実上標準になっている)、のでしょう。
yambejp

2017/03/28 08:32

先頭に関してはたしかに0はじまりはNGですね。 まぁ一般に010は8ですからね ただ前回の補足にも「10.001.002.003」は有効って書きましたよね? 今回の質問に関しては「10.001.002.003」が間違ったIPアドレス だと質問者さんが定義していないので、別の人間が勝手に間違いだと 切り捨てること自体ナンセンスでしょう。 質問者さんの定義が正しいのであってRFCに準拠する必要はありません 前述したとおり「167838211」だって定義次第で正しいIPアドレスです
think49

2017/03/28 12:01 編集

To: tacsheaven さん > 大元の RFC952 では単に digit (#)としか記述しておらず、 「<octet> ::= <0 to 255 decimal>」の部分でしょうか。 それでも「0パディング数値を8進数として扱う」規定はないので実装依存になる問題は残ってしまうのですね。 実装依存な挙動に頼った実装をすると痛い目を見る事が多いので、個人的には「0パディングしたIPv4アドレス」お勧めしがたい文法ではあります。 https://tools.ietf.org/html/rfc952 To: yambejp さん > 先頭に関してはたしかに0はじまりはNGですね。 > まぁ一般に010は8ですからね > ただ前回の補足にも「10.001.002.003」は有効って書きましたよね? 「先頭」は第一オクテットを表しているのでしょうか。 第二オクテット以下が 0*[0-7] で構成されているので第二オクテット以下の8進数値/10進数値が同値になっていますが、http://10.001.002.030/ なら http://10.1.2.24/ になりますので、第一オクテットだけ「0パディング数値」を除外する意味はないと思います。 「8進数IPv4アドレス」と「10進数IPv4アドレス」の表記ゆれを防ぐなら「各オクテット数値が7以下の場合に限り、前方を0パディングしても良い」のルールに則って正規表現を書くべきですが、正規表現が複雑化するだけでメリットがないように思いました。 > 質問者さんの定義が正しいのであってRFCに準拠する必要はありません そうかもしれませんが、仕様違反の問題を認識していながら「質問者の要件だけ」を忠実に再現するのは不親切な気がたので横入りしてしまいました。お節介ですみません。
yambejp

2017/03/28 11:28

think49さんの仰る通りでした、完全に思い込みでした これについては申し開きようがありません、申し訳ないです。
yambejp

2017/03/28 11:43 編集

あらためて考えると255.255.255.255まで考慮すると 「0377.0377.0377.0377」までが理論的に有効ですね ただしOSによって挙動が違うようです。 当然0で埋める場合もっと桁数が上がっても良いので 理論的には正しくても運用できないものになりそうです。 (例えば000000001.2.3.4だって構わないわけだから) また例えば0.0.0.0を有効とする場合など想定が必要になり 正規表現でチェックするには多少無理があるようです
guest

0

投稿2017/03/27 08:33

退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Zuishin

2017/03/27 08:37

これ、バリデーションに使えますか? エスケープするだけじゃ?
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問