如何通过在python中排除RFC1918私有地址来匹配IPV4正则表达式模式

时间:2018-06-26 05:29:35

标签: python regex python-2.7

import re
text='''10.11.0.0'''

pattern=re.compile(r'(\b(\d|\d{2}|1\d{2}|2[0-5]{2})\.(\d|\d{2}|1\d{2}|2[0-5] 
{2})\.(\d|\d{2}|1\d{2}|2[0-5]{2})\.(\d|\d{2}|1\d{2}|2[0-5]{2})\b)')

#pattern=re.compile(r'\b((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(\.|$)){4}\b')
matches=pattern.finditer(text)

for match in matches:
  print(match.group())

这是查找所有IPV4地址的正则表达式模式,但我需要排除RFC1918地址。请提供建议。

2 个答案:

答案 0 :(得分:1)

根据this reference,IP地址正则表达式为\b(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}\b

您要避免匹配以10192.168开头的IP地址和以172开头的特定地址范围。

使用

\b(?!10\.|192\.168\.|172\.(?:1[6-9]|2[0-9]|3[01])\.)(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}\b

请参见regex demo

详细信息

  • \b-单词边界
  • (?!10\.|192\.168\.|172\.(?:1[6-9]|2[0-9]|3[01])\.)-如果下一步出现RFC1918地址“标记”,则负向超前将使匹配失败:
    • 10\.-10.
    • 192\.168\.-192.168.
    • 172\.(?:1[6-9]|2[0-9]|3[01])\.-172.,然后是16到31和.
  • (?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)-一个八位字节的正则表达式(请注意,非捕获组,您可以将此模式与re.findall一起使用,以方便的方式返回所有匹配项,而无需使用{{1 }})
  • re.finditer-点号后跟八位字节的3次重复
  • (?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}-单词边界

Python demo

\b

答案 1 :(得分:0)

此正则表达式与RFC1918中的地址匹配:

(^192\.168\.([0-9]|[0-9][0-9]|[0-2][0-5][0-5])\.([0-9]|[0-9][0-9]|[0-2][0-5][0-5])$)|(^172\.([1][6-9]|[2][0-9]|[3][0-1])\.([0-9]|[0-9][0-9]|[0-2][0-5][0-5])\.([0-9]|[0-9][0-9]|[0-2][0-5][0-5])$)|(^10\.([0-9]|[0-9][0-9]|[0-2][0-5][0-5])\.([0-9]|[0-9][0-9]|[0-2][0-5][0-5])\.([0-9]|[0-9][0-9]|[0-2][0-5][0-5])$)

在这里找到:https://www.regextester.com/95489

要获得理想的结果,只需匹配所有IP,然后删除与您要排除的IP匹配的IP(保持与您自己的示例相近):

import re
text='''10.11.0.0', 192.168.1.1, 123.4.5.6'''

pattern=re.compile(r'(\b(\d|\d{2}|1\d{2}|2[0-5]{2})\.(\d|\d{2}|1\d{2}|2[0-5]{2})\.(\d|\d{2}|1\d{2}|2[0-5]{2})\.(\d|\d{2}|1\d{2}|2[0-5]{2})\b)')
exclude=re.compile(r'(^192\.168\.([0-9]|[0-9][0-9]|[0-2][0-5][0-5])\.([0-9]|[0-9][0-9]|[0-2][0-5][0-5])$)|(^172\.([1][6-9]|[2][0-9]|[3][0-1])\.([0-9]|[0-9][0-9]|[0-2][0-5][0-5])\.([0-9]|[0-9][0-9]|[0-2][0-5][0-5])$)|(^10\.([0-9]|[0-9][0-9]|[0-2][0-5][0-5])\.([0-9]|[0-9][0-9]|[0-2][0-5][0-5])\.([0-9]|[0-9][0-9]|[0-2][0-5][0-5])$)')

matches = pattern.finditer(text)
filtered = [match.group() for match in matches if not exclude.match(match.group())]

for match in filtered:
  print(match)

请注意,如果您希望列表很大,那么对于相同的结果,也可以使用生成器理解而不是列表理解。