我试图从查看站点中的某些徽标和链接中排除一些内部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
Run Code Online (Sandbox Code Playgroud)
引用句点,将X替换为\d+
,然后将它们与所有管道连接在一起:
var 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.
];
var allowedRegexStr = '^(?:' +
allowedIPpatterns.
join('|').
replace(/\./g, '\\.').
replace(/X/g, '\d+') +
')$';
var allowedRegexp = new RegExp(allowedRegexStr);
Run Code Online (Sandbox Code Playgroud)
然后,您已经准备就绪:
'10.1.2.3'.match(allowedRegexp) // => ['10.1.2.3']
'100.1.2.3'.match(allowedRegexp) // => null
Run Code Online (Sandbox Code Playgroud)
如果您的输入甚至根本不是合法的IP地址,则可以将更'\d+'
改为仅与有效字节值匹配的内容,例如 '(?:\\d{1,2}|1\\d{2}|2[0-4]\\d|25[0-5])'
。
怎么运行的:
首先,我们必须将各个IP模式转换为符合其意图的正则表达式。“格式为'12 .122.X.X'的所有IP”的一个正则表达式是:
^12\.122\.\d+\.\d+$
^
表示匹配必须从字符串的开头开始;否则,112.122.XX IP也将匹配。12
等:数字匹配自己\.
:正则表达式中的句点完全匹配任何字符;我们需要字面量,因此我们在前面加一个反斜杠。\d
简称:[0-9]
; 匹配任何数字。+
:表示“ 1或更多”-在这种情况下为1或更多数字。$
:类似于^
,这意味着匹配必须在字符串的末尾结束。因此,我们将IP模式变成这样的正则表达式。对于单个模式,可以使用如下代码:
var regexStr = `^` + ipXpattern.
replace(/\./g, '\\.').
replace(/X/g, '\\d+') +
`$`;
Run Code Online (Sandbox Code Playgroud)
刚刚替换所有.
s的\.
,并X
带有S \d+
和粘^
和$
的末端。
在正则表达式中,交替 this|that
匹配与this
或匹配的任何内容that
。因此,如果我们将列表转换为表单的单个正则表达式,则可以立即检查是否与所有IP匹配re1|re2|re3|...|relast
。
然后,我们可以进行一些重构以使正则表达式匹配器的工作更轻松;在这种情况下,由于所有正则表达式都将具有^...$
,因此我们可以将这些约束移出各个正则表达式,然后将它们放在整个对象上:^(10\.\d+\.\d+\.\d+|12\.122\.\d+\.\d+|...)$
。括号可防止^
仅仅是第一个模式的$
一部分,而只是最后一个模式的一部分。但是,由于简单的括号捕获以及组,我们并不需要捕捉什么,我代替他们与非分组版本(?:
.. )
。
在这种情况下,我们可以对巨型字符串执行一次全局搜索和替换,而不必对每个模式进行单独的搜索和替换。所以结果就是上面的代码:
var allowedRegexStr = '^(?:' +
allowedIPpatterns.
join('|').
replace(/\./g, '\\.').
replace(/X/g, '\d+') +
')$';
Run Code Online (Sandbox Code Playgroud)
那仍然只是一个字符串。我们必须将其转换为实际RegExp
对象以进行匹配:
var allowedRegexp = new RegExp(allowedRegexStr);
Run Code Online (Sandbox Code Playgroud)
如所写,这不会过滤掉非法IP-例如,10.1234.5678.9012
将匹配第一个模式。如果您想将各个字节值限制在0-255的十进制范围内,则可以使用比更为复杂的regex \d+
,如下所示:
(?:\\d{1,2}|1\\d{2}|2[0-4]\\d|25[0-5])
Run Code Online (Sandbox Code Playgroud)
意思是“任何一个或两个数字,或“ 1”后跟任何两个数字,或“ 2”,后跟“ 0”到“ 4”中的任何一个,再跟任何数字,或“ 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\....
Run Code Online (Sandbox Code Playgroud)
但您不必查看它,只需与它匹配即可。:)