写论文写累了,忽然想起以前面试时的一道题:怎样用正则表达式匹配IPV4地址?在网上找到两篇很好的英文文章,把相关内容翻译综合一下,与诸君共享。
原文链接:
http://blogs.msdn.com/b/oldnewthing/archive/2006/05/22/603788.aspx
http://answers.oreilly.com/topic/318-how-to-match-ipv4-addresses-with-regular-expressions/
写一个正则表达式匹配IPV4地址说容易也容易,说难也难,取决于需要的准确度。简单起见,这里只考虑点分十进制的IPV4地址。
最简单的方式是把IPV4地址看做四段十进制数字串,由三个点号隔开,可以采用如下写法:
^\d+\.\d+\.\d+\.\d+$
就其本身而言没有问题,但会错误地匹配"448.90210.0.65535"这样的字符串,而一个恰当的IPV4表示法中每个域中的值不应大于255。但写一个匹配0到255的整数的正则表达式并不容易,因为正则表达式不理解算术,而是单纯基于文本。考虑下面一些情况:
单独的一个数字(表示0-9)一个非零数字后紧跟着另外一个数字(表示10-99)"1"后面跟着两个数字(表示100-199)"2"后面跟着一个"0"到"4"间的数字,后面又跟着一个数字(表示200-249)"25"后面跟着一个"0"到"5"间的数字(表示250-255)
根据上面的分析,来试着写匹配0-255的正则表达式:
^\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]$
将前两项合并,上式变成:
^[1-9]?\d|1\d\d|2[0-4]\d|25[0-5]$
然后,将上面这个式子重复4次,中间以点号隔开即可,如下所示:
^([1-9]?\d|1\d\d|2[0-4]\d|25[0-5])\.([1-9]?\d|1\d\d|2[0-4]\d|25[0-5])\.([1-9]?\d|1\d\d|2[0-4]\d|25[0-5])\.([1-9]?\d|1\d\d|2[0-4]\d|25[0-5])$