简体   繁体   English

PHP RegExp恢复断言以获得相反的匹配

[英]PHP RegExp revert assertion to get the opposite match

this is my first question so please be nice :). 这是我的第一个问题所以请你好:)。 I'm trying to build a regexp to get an array of IPs that are both valid (OK, at least with the proper IPv4 format) and NOT a private IP according to RFC 1918. So far, I've figured out a way to get exactly the opposite, I mean succcssfuly matching private IPs, so all what I need is a way to revert the assertion. 我正在尝试构建一个正则表达式,以获得有效的IP数组(确定,至少使用正确的IPv4格式),而不是根据RFC 1918的私有IP。到目前为止,我已经找到了一种方法完全相反,我的意思是succcssfuly匹配私有IP,所以我需要的是一种方法来恢复断言。 This is the code so far: 这是到目前为止的代码:

// 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
  )
)

And what I want as result is: 我想要的结果是:

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

I've tried changing the first part of the expression (the lookahead) to be negative (?!) but this messes up the results and don't even switch the result. 我已经尝试将表达式的第一部分(前瞻)更改为否定(?!)但这会弄乱结果,甚至不会切换结果。

If you need any more informartion please feel free to ask, many thanks in advance. 如果您需要更多信息,请随时提出,非常感谢您提前。

There is a PHP function for that: filter_var() . 有一个PHP函数: filter_var() Check these constants: FILTER_FLAG_IPV4 , FILTER_FLAG_NO_PRIV_RANGE . 检查这些常量: FILTER_FLAG_IPV4FILTER_FLAG_NO_PRIV_RANGE

However if you still want to solve this with regular expressions, I suggest you split your problem in two parts: first you extract all the IP addresses, then you filter out the private ones. 但是,如果您仍想使用正则表达式解决此问题,我建议您将问题分为两部分:首先提取所有IP地址,然后筛选出私有地址。

If all you want to do is to exclude a relatively small range of ip's, you could do this (if I didn't make any typo's): 如果您只想排除相对较小范围的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)/

Example in Perl: 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";
}

Output: 输出:

200.52.85.20 200.52.85.20
200.44.85.20 200.44.85.20

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM