Javascript多个正则表达式模式

nee*_*meg 0 javascript regex

我试图从查看站点中的某些徽标和链接中排除一些内部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)

Mar*_*eed 5

引用句点,将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)

但您不必查看它,只需与它匹配即可。:)