PHP RegExp还原断言以获得相反的匹配


PHP RegExp revert assertion to get the opposite match

这是我的第一个问题,所以请注意:)。我正试图构建一个正则表达式,以获得一组IP,这些IP既有效(好吧,至少使用正确的IPv4格式),又不是根据RFC 1918的私有IP。到目前为止,我已经找到了一种完全相反的方法,我的意思是成功地匹配私人IP,所以我所需要的只是一种恢复断言的方法。这是迄今为止的代码:

// This is an example string
$ips = '10.0.1.23, 192.168.1.2, 172.24.2.189, 200.52.85.20, 200.44.85.20';
preg_match_all('/(?:10'.'d{1,3}|172'.(?:1[6-9]|2'd|3[01])|192'.168)'.'d{1,3}'.'d{1,3}/', $ips, $matches);
print_r($matches);
// Prints:
Array
(
  [0] => Array
  (
    [0] => 10.0.1.23
    [1] => 192.168.1.2
    [2] => 172.24.2.189
  )
)

我想要的结果是:

Array
(
  [0] => Array
  (
    [0] => 200.52.85.20
    [1] => 200.44.85.20
  )
)

我曾尝试将表达式的第一部分(展望)更改为负数(?!),但这会混淆结果,甚至不会切换结果。

如果您需要更多信息,请随时询问,非常感谢。

有一个PHP函数:filter_var()。检查这些常量:FILTER_FLAG_IPV4FILTER_FLAG_NO_PRIV_RANGE

然而,如果你仍然想用正则表达式来解决这个问题,我建议你把问题分成两部分:首先提取所有的IP地址,然后过滤掉私有地址。

如果你只想排除相对较小范围的ip,你可以这样做(如果我没有错别字的话):

/(?!'b(?:10'.'d{1,3}|172'.(?:1[6-9]|2'd|3[01])|192'.168)'.'d{1,3}'.'d{1,3}'b)'b('d{1,3}'.'d{1,3}'.'d{1,3}'.'d{1,3}'b)/

Perl示例:

use strict;
use warnings;
my @found = '10.0.1.23, 192.168.1.2, 172.24.2.189, 200.52.85.20, 200.44.85.20' =~
/
(?!
   'b
   (?:
        10'.'d{1,3}
      |
        172'.
        (?:
            1[6-9]
          | 2'd
          | 3[01]
        )
      |
        192'.168
   )
   '.'d{1,3}
   '.'d{1,3}
   'b
)
'b('d{1,3}'.'d{1,3}'.'d{1,3}'.'d{1,3}'b)
/xg;
for (@found) {
    print "$_'n";
}

输出:

200.52.85.20
200.44.85.20