一部の内部IPアドレスと一部の内部IPアドレス形式を、サイト内の特定のロゴとリンクの表示から除外しようとしています。複数の範囲のIPアドレスがあります(以下にサンプルを示します)。javascriptを使用して、以下のリストのすべてのIPアドレスに一致する正規表現を作成することは可能ですか?
10.X.X.X
12.122.X.X
12.211.X.X
64.X.X.X
64.23.X.X
74.23.211.92
and 10 more
一部の内部IPアドレスと一部の内部IPアドレス形式を、サイト内の特定のロゴとリンクの表示から除外しようとしています。複数の範囲のIPアドレスがあります(以下にサンプルを示します)。javascriptを使用して、以下のリストのすべてのIPアドレスに一致する正規表現を作成することは可能ですか?
10.X.X.X
12.122.X.X
12.211.X.X
64.X.X.X
64.23.X.X
74.23.211.92
and 10 more
ピリオドを引用し、Xをに置き換え、\d+
パイプですべて結合します。
const allowedIPpatterns = [
"10.X.X.X",
"12.122.X.X",
"12.211.X.X",
"64.X.X.X",
"64.23.X.X",
"74.23.211.92" //, etc.
];
const allowedRegexStr = '^(?:' +
allowedIPpatterns.
join('|').
replace(/\./g, '\\.').
replace(/X/g, '\\d+') +
')$';
const allowedRegexp = new RegExp(allowedRegexStr);
これで準備は完了です。
'10.1.2.3'.match(allowedRegexp) // => ['10.1.2.3']
'100.1.2.3'.match(allowedRegexp) // => null
使い方:
まず、個々のIPパターンをその意図に一致する正規表現に変換する必要があります。「「12.122.XX」形式のすべてのIP」の正規表現の1つは、次のとおりです。
^12\.122\.\d+\.\d+$
^
一致は文字列の先頭から開始する必要があることを意味します。そうしないと、112.122.XXIPも一致します。12
など:数字は自分自身と一致します\.
:正規表現のピリオドはすべての文字に一致します。文字通りのピリオドが必要なので、前に円記号を付けます。\d
:の省略形[0-9]
; 任意の数字に一致します。+
:は「1つ以上」を意味します。この場合は1桁以上です。$
:と同様に^
、これは一致が文字列の最後で終了する必要があることを意味します。したがって、IPパターンをそのような正規表現に変換します。個々のパターンには、次のようなコードを使用できます。
const regexStr = `^` + ipXpattern.
replace(/\./g, '\\.').
replace(/X/g, '\\d+') +
`$`;
.
これは、すべてのsをと\.
に置き換えて、とを両端に貼り付けます。X
\d+
^
$
(2倍のバックスラッシュに注意してください。文字列解析と正規表現解析の両方でバックスラッシュが使用されるため、リテラルパーサーを通過して正規表現パーサーに到達する場合は、2倍にする必要があります。)
正規表現では、交互 はまたはのいずれかthis|that
に一致するものすべてに一致します。したがって、リストをフォームの単一の正規表現に変換すると、すべてのIPとの一致を一度に確認できます。this
that
re1|re2|re3|...|relast
次に、正規表現マッチャーの作業を簡単にするためにリファクタリングを行うことができます。この場合、すべての正規表現にが含まれるため^...$
、これらの制約を個々の正規表現から移動して、全体に適用できます^(10\.\d+\.\d+\.\d+|12\.122\.\d+\.\d+|...)$
。括弧^
は、が最初のパターンの一部にすぎないよう$
にし、最後のパターンの一部にすぎないようにします。ただし、単純な括弧はグループ化だけでなくキャプチャーも行うため、何もキャプチャーする必要がないため、グループ化されていないバージョンに置き換えまし(?:
た)
。
この場合、各パターンで個別にではなく、巨大な文字列に対してグローバル検索と置換を1回実行できます。したがって、結果は上記のコードになります。
const allowedRegexStr = '^(?:' +
allowedIPpatterns.
join('|').
replace(/\./g, '\\.').
replace(/X/g, '\\d+') +
')$';
それはまだ単なる文字列です。マッチングを行うには、それを実際のRegExp
オブジェクトに変換する必要があります。
const allowedRegexp = new RegExp(allowedRegexStr);
書かれているように、これは不正なIPを除外しません-たとえば、10.1234.5678.9012
最初のパターンに一致します。個々のバイト値を0〜255の10進範囲に制限する場合は、次のように、よりも複雑な正規表現を使用できます\d+
。
(?:\d{1,2}|1\d{2}|2[0-4]\d|25[0-5])
これは、「任意の1桁または2桁、または「1」の後に任意の2桁、または「2」の後に「0」から「4」のいずれか、その後に任意の数字、または「25」の後に「0」のいずれかに一致します。 「5」まで」。をそれに置き換える\d
と、完全な文字列結合式が次のようになります。
const allowedRegexStr = '^(?:' +
allowedIPpatterns.
join('|').
replace(/\./g, '\\.').
replace(/X/g, '(?:\\d{1,2}|1\\d{2}|2[0-4]\\d|25[0-5])') +
')$';
そして、実際の正規表現をはるかに扱いにくくします。
^(?:10\.(?:\d{1,2}|1\d{2}|2[0-4]\d|25[0-5])\.(?:\d{1,2}|1\d{2}|2[0-4]\d|25[0-5]).(?:\d{1,2}|1\d{2}|2[0-4]\d|25[0-5])|12\.122\....
しかし、あなたはそれを見る必要はありません、ただそれと一致します。:)
正規表現でそれを行うことはできますが、特にJavaScriptは冗長な正規表現をサポートしていないため、きれいにはなりません。つまり、コメントなしで1行の巨大な正規表現である必要があります。さらに、正規表現は、数値の範囲を一致させるには適していません。これに対処するためのより良いツールがあると思います。
さて、OK、ここに行きます(あなたが提供したサンプルのために):
var myregexp = /\b(?:74\.23\.211\.92|(?:12\.(?:122|211)|64\.23)\.(?:25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])\.(?:25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])|(?:10|64)\.(?:25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])\.(?:25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])\.(?:25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9]))\b/g;
冗長な(「読み取り可能な」)正規表現として:
\b # start of number
(?: # Either match...
74\.23\.211\.92 # an explicit address
| # or
(?: # an address that starts with
12\.(?:122|211) # 12.122 or 12.211
| # or
64\.23 # 64.23
)
\. # .
(?:25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])\. # followed by 0..255 and a dot
(?:25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9]) # followed by 0..255
| # or
(?:10|64) # match 10 or 64
\. # .
(?:25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])\. # followed by 0..255 and a dot
(?:25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])\. # followed by 0..255 and a dot
(?:25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9]) # followed by 0..255
)
\b # end of number
/^(X|\d{1,3})(\.(X|\d{1,3})){3}$/
それをする必要があります。
実際に「X」文字と一致する必要がない場合は、次のように使用できます。
\b(?:\d{1,3}\.){3}\d{1,3}\b
それ以外の場合は、提供されているソリューションcebarrettを使用します。
私はあなたがここで何を達成しようとしているのか完全にはわかりません(他の誰かもそうではないようです)。
ただし、検証の場合は、RegExを使用しないIPアドレスを検証するための解決策があります。まず、入力文字列をドットで分割します。次に、数値にparseIntを使用して、255より大きくないことを確認します。
function ipValidator(ipAddress) {
var ipSegments = ipAddress.split('.');
for(var i=0;i<ipSegments.length;i++)
{
if(parseInt(ipSegments[i]) > 255){
return 'fail';
}
}
return 'match';
}
次のコマンドを実行すると、「match」が返されます。
document.write(ipValidator('10.255.255.125'));
これは'fail'を返しますが:
document.write(ipValidator('10.255.256.125'));
これは、いくつかの例を含むjsfiddleの注目のバージョンです。http ://jsfiddle.net/VGp2p/2/