验证IP地址——正则表达式详解

Posted Michael Jackma

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了验证IP地址——正则表达式详解相关的知识,希望对你有一定的参考价值。

题目一:

判断一个字符串是否符合ipv4地址,返回true或者false
比如:输入“127.0.0.1”,返回true
     输入"256.1.2.3",返回false

1、题目分析:

IPv4地址由4个十进制数和3个点组成,每个十进制数范围为0-255。比如,127.0.0.1。               

⚠️注意:IPv4地址内的数不会以0开头。比如,地址127.10.111.01 是不合法的。

2、代码实现:

import re
def is_ipv4(str):
    pattern = "([1-9]?\\d|1\\d2|2[0-4]\\d|25[0-5])(\\.([1-9]?\\d|1\\d2|2[0-4]\\d|25[0-5]))3$"
    result = re.match(pattern, str)
    if result:
        return "true"
    else:
        return "false"

print('127.0.0.1 :', is_ipv4('127.0.0.1'))
print('256.1.2.3 :', is_ipv4('256.1.2.3'))
print('127.0.0.01 :', is_ipv4('127.0.0.01'))

3、代码解析:

pattern = "([1-9]?\\d|1\\d2|2[0-4]\\d|25[0-5])(\\.([1-9]?\\d|1\\d2|2[0-4]\\d|25[0-5]))3$"
分段匹配0-255的整数:
模式\\d[1-9]\\d[1-9]?\\d1\\d22[0-4]\\d25[0-5]
匹配字符串0-910-990-99100-199200-249250-255
本文涉及到的Python正则表达式模式如下表所示:
模式功能描述
$匹配字符串的末尾
[...]用来表示一组字符,单独列出:[amk] 匹配 ‘a’, ‘m’ 或 ‘k’
\\d匹配任意数字,等价于 [0-9]
\\.匹配 ‘.’
(re)对正则表达式分组并记住匹配的文本
a|b匹配a或b
m, n

匹配m到n次由前面的正则表达式定义的片段,贪婪方式

"ab3,5":表示一个字符串有一个a跟着3到5个b。

n

精确匹配n个表达式。

例如,o2 不能匹配 ‘Bob’ 中的 ‘o’,但是能匹配 ‘food’ 中的 ‘oo’

*

匹配0次或无限次。

"ab*":表示一个字符串有1个a后面跟着0个或若干个b。("a", "ab", "abbb",……)

+

匹配1次或无限次。

"ab+":表示一个字符串有1个a后面跟着至少1个b。("ab", "abb","abbb",……)

?

匹配0次或1次。

"ab?":表示一个字符串有1个a后面跟着0个或者1个b。("a", "ab")

re.match函数

正则表达式-英文regular expression,缩写为 re 。

函数语法:
re.match(pattern, string)

函数参数说明:
pattern表示正则表达式模式,string表示要匹配的字符串。

re.match从字符串的起始位置开始与模式进行匹配,若匹配成功,则返回一个匹配对象,若匹配失败,则返回None。

 

题目二:

编写一个函数来验证输入的字符串是否是有效的IPv4或IPv6地址。

1、题目分析:

IPv6地址由8组16进制数和7个(":")组成,每组表示16比特。
比如, 2001:0db8:85a3:0000:0000:8a2e:0370:7334是一个有效的地址。 

⚠️注意:字符串里没有空格或者其他特殊字符,每组16进制数为4位。

2、代码实现:

import re

def validIPAddress(IP):
    pattern_IPv4 = "([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]))3$"
    pattern_IPv6 = '([\\dA-Fa-f]1,4\\:)7[\\dA-Fa-f]1,4$'
    if re.match(pattern_IPv4, IP):
        return 'IPv4'
    if re.match(pattern_IPv6, IP):
        return 'IPv6'
    return 'Neither'

print(validIPAddress('172.16.254.1'))
print(validIPAddress('256.256.256.256'))
print(validIPAddress('1.1.1.01'))
print(validIPAddress('2001:0db8:85a3:0:0:8A2E:0370:7334'))
print(validIPAddress('2001:0db8:85a3:0:0:8A2E:0370:73340'))
print(validIPAddress('2001:0db8::0:0:8A2E:0370:7334'))

3、代码解析:

pattern_IPv6 = '([\\dA-Fa-f]1,4\\:)7[\\dA-Fa-f]1,4$'
每一位十六进制数:
模式[\\dA-Fa-f]
匹配字符串(不区分大小写)

0 1 2 3 4 5 6 7 8 9 a b c d e f

0 1 2 3 4 5 6 7 8 9 A B C D E F

 

如何在 Objective-C 中使用正则表达式验证 IP 地址?

【中文标题】如何在 Objective-C 中使用正则表达式验证 IP 地址?【英文标题】:How to validate an IP address with regular expression in Objective-C? 【发布时间】:2010-12-13 08:14:43 【问题描述】:

如何在 Objective-C 中验证 IP 地址?

【问题讨论】:

我不明白。为什么一定是正则表达式? 如果没有内置的正则表达式库,你可能会更好地使用 NSScanner。 如何使用 NSSCanner 做到这一点? 虽然我支持 NSScanner,但在 Obj-C 中(实际上在 Cocoa 和 Cocoa-Touch 中),IS 和 NSRegularExpression 都很好。有几个堆栈溢出问题和答案用于将 IP 地址与正则表达式匹配。 【参考方案1】:

这是一个使用现代 inet_pton 的类别,它将为有效的 IPv4 或 IPv6 字符串返回 YES。

    #include <arpa/inet.h>

    @implementation NSString (IPValidation)

    - (BOOL)isValidIPAddress
    
        const char *utf8 = [self UTF8String];
        int success;

        struct in_addr dst;
        success = inet_pton(AF_INET, utf8, &dst);
        if (success != 1) 
            struct in6_addr dst6;
            success = inet_pton(AF_INET6, utf8, &dst6);
        

        return success == 1;
    

    @end

【讨论】:

供以后参考,成功 == 1 ? TRUE :不需要 FALSE。一个简单的成功 == 1 就可以了。【参考方案2】:

这是一种可能也有帮助的替代方法。假设您有一个 NSString*,其中包含您的 IP 地址,称为 ipAddressStr,格式为 a.b.c.d

int ipQuads[4];
const char *ipAddress = [ipAddressStr cStringUsingEncoding:NSUTF8StringEncoding];

sscanf(ipAddress, "%d.%d.%d.%d", &ipQuads[0], &ipQuads[1], &ipQuads[2], &ipQuads[3]);

@try 
   for (int quad = 0; quad < 4; quad++) 
      if ((ipQuads[quad] < 0) || (ipQuads[quad] > 255)) 
         NSException *ipException = [NSException
            exceptionWithName:@"IPNotFormattedCorrectly"
            reason:@"IP range is invalid"
            userInfo:nil];
         @throw ipException;
      
   

@catch (NSException *exc) 
   NSLog(@"ERROR: %@", [exc reason]);

如果您需要该级别的验证,您可以修改 if 条件块以遵循 RFC 1918 准则。

【讨论】:

Alex,你的意思是在 sscanf 的每个 ipQuad 参数前加一个“&”吗? 我本来打算,但我没有。添加此评论后,我将编辑答案。另外,我把ipQuads的类型从unsigned char改成了unsigned int,这样测试就有可能失败。 由于 iOS SDK 中提供了 iOS 4 RegExps:developer.apple.com/library/IOs/#documentation/Foundation/… ...所以,如果您想将此答案标记为已弃用“但对信息或教育目的有用”会有所帮助:) 比较ipQuads[quad] &lt; 0 总是假的,因为ipQuads[quad]unsigned【参考方案3】:

斯威夫特版:

func isIPAddressValid(ip: String) -> Bool 
    guard let utf8Str = (ip as NSString).utf8String else 
        return false
    

    let utf8:UnsafePointer<Int8> = UnsafePointer(utf8Str)
    var success: Int32

    var dst: in_addr = in_addr()
    success = inet_pton(AF_INET, utf8, &dst)
    if (success != 1) 
        var dst6: in6_addr? = in6_addr()
        success = inet_pton(AF_INET6, utf8, &dst6);
    

    return success == 1

【讨论】:

【参考方案4】:

您可以做的一个技巧是测试 inet_aton BSD 调用的返回,如下所示:

#include <arpa/inet.h>

- (BOOL)isIp:(NSString*)string
    struct in_addr pin;
    int success = inet_aton([string UTF8String],&pin);
    if (success == 1) return TRUE;
    return FALSE;

但是请注意,如果字符串包含任何格式的 IP 地址,这将验证字符串,它不限于点分格式。

【讨论】:

仅供参考:inet_aton 已被弃用,取而代之的是处理 IPv6 的 inet_pton 如果您从 if 检查返回布尔值,请只返回 if 检查本身,即return success == 1

以上是关于验证IP地址——正则表达式详解的主要内容,如果未能解决你的问题,请参考以下文章

求一个正则表达式验证IP地址

使用正则表达式在python中验证IP地址[重复]

如何在 Objective-C 中使用正则表达式验证 IP 地址?

使用正则表达式验证IP地址

正则表达式验证Ip地址(绝对正确)

正则表达式验证Ip地址(绝对正确)