zoukankan      html  css  js  c++  java
  • python中利用正则表达式匹配ip地址

    现在有一道题目,要求利用python中re模块来匹配ip地址,我们应如何着手?

    首先能想到的是ip地址是数字,正则表达式是如何匹配数字的呢?

    d或[0-9]

    对于这个问题,不要一下子上来就写匹配模式,应该一步步分解,把复杂的问题简单化

    比如ip地址,我们可以总结一下规律

    1. 它是一个字符串

    2. 字符串内部是由4个1-3位的数字和3个.组成

    3. 数字的范围是0-255

    接下来,我们先试一下匹配第1个数字

    第一步:尝试匹配192.168.100.123中的192

    >>> import re
    >>> re.search(r"ddd", "192.168.100.123")
    <_sre.SRE_Match object; span=(0, 3), match='192'>

    第二步:尝试匹配192.168.100.123中的192.

    值得注意的是,由于正则表达式中的元字符 . 表示除了 之外的任意一个字符,我们需要匹配 . 本身,就需要用 进行转义

    >>> re.search(r"ddd.", "192.168.100.12")
    <_sre.SRE_Match object; span=(0, 4), match='192.'>

    第三步:尝试匹配192.168.100.123的整体

    >>> re.search(r"ddd.ddd.ddd.ddd", "192.168.100.123")
    <_sre.SRE_Match object; span=(0, 15), match='192.168.100.123'>

    这样写有什么问题呢?

    1. 我们的数字并不都是3位,像192.168.100.1这样的,我们的匹配模式就失效了

    >>> re.search(r"ddd.ddd.ddd.ddd", "192.168.100.1")
    >>> 

    2. 不够美观

    第四步:优化误区一

    很多人一上手,就写成了[0-255],这不就是数字的范围0-255吗?我们说,这样是不对的

    正则表达式中,真正要匹配的永远是字符串,一个字符串内部是由三位的数字构成的,如果需要匹配三位数字的形式,就需要用到[0-9][0-9][0-9]或ddd,用一个[0-9]表示的只能匹配一位,[0-255]这种错误的写法也只能匹配到一位0-9之间的数字

    >>> re.search(r"[0-255]", "255")
    <_sre.SRE_Match object; span=(0, 1), match='2'>

    如下图,第一个[0-255]匹配到了1, .匹配到了.

    这个ip地址中根本没有 1. 这种形式的,所以返回了None

    >>> re.search(r"[0-255].[0-255].[0-255].[0-255]", "192.168.100.1")
    >>> 

    优化误区二:

    既然上面的不对,那能不能把255分解成 2, 5, 5, 我们匹配时能否写成[0-2][0-5][0-5],看似是没问题的,我们来试试

    >>> re.search(r"[0-2][0-5][0-5]", "192.168.100.1")
    <_sre.SRE_Match object; span=(8, 11), match='100'>
    >>> 

    为什么192没有匹配到?168也没有匹配到?因为数字的十位和个位最大只能是5,超过5的肯定没法匹配

    第五步:继续优化

    我们来看下0-255这个范围,当百位是0或者1时,十位和个位可以是[0-9],也就是d,当百位是2时,十位是[0-4]时,个位可以是d,当百位是2时,十位是5时,个位只能是[0-5],那么,我们是不是可以这样来写,比如匹配192,匹配模式可以写成

    [01]dd|2[0-4]d|25[0-5]

    如果有重复的,我们可以给上面的模式加上 {n} 表示重复匹配前面的字符n次

    >>> re.search(r"(([01]dd|2[0-4]d|25[0-5]d).){3}([01]dd|2[0-4]d|25[0-5]d)", "192.168.100.123")
    <_sre.SRE_Match object; span=(0, 15), match='192.168.100.123'>

    看似正确了,但是还是匹配不到数字 1 ,因为我们的百位是[01],意味这如果是 1 的情况下,我们的结果是001,但ip地址是不能写成001, 002的

    >>> re.search(r"(([01]dd|2[0-4]d|25[0-5]d).){3}([01]dd|2[0-4]d|25[0-5]d)", "192.168.100.1")
    >>> 
    >>> re.search(r"(([01]dd|2[0-4]d|25[0-5]d).){3}([01]dd|2[0-4]d|25[0-5]d)", "192.168.100.001")
    <_sre.SRE_Match object; span=(0, 15), match='192.168.100.001'>
    >>> 

    可以通过{0,1}来优化,表示前面的字符重复0-1次,也可以用 ?

    >>> re.search(r"(([01]{0,1}d{0,1}d|2[0-4]d|25[0-5]d).){3}([01]{0,1}d{0,1}d|2[0-4]d|25[0-5]d)", "192.168.100.1")
    <_sre.SRE_Match object; span=(0, 13), match='192.168.100.1'>
    
    >>> re.search(r"(([01]?d?d|2[0-4]d|25[0-5]d).){3}([01]?d?d|2[0-4]d|25[0-5]d)", "192.168.100.1")
    <_sre.SRE_Match object; span=(0, 13), match='192.168.100.1'>

    这样,当数字只有个位时,百位的0匹配0次,十位的0匹配0次,只留下个位数字[0-9]

  • 相关阅读:
    Echarts之内嵌圆环图v5.1.2
    VueX+VueRouter+Cookie实现简单登录页
    命令行安装MySQL
    mysql常用语句
    网际互联及OSI七层模型:
    阿里ICON图标,使用教程
    前端开发小技巧整理
    SQL语句
    web笔记
    jQuery
  • 原文地址:https://www.cnblogs.com/my_captain/p/9210605.html
Copyright © 2011-2022 走看看