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

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

【问题讨论】:

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

标签: objective-c regex ip-address


【解决方案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
    猜你喜欢
    • 2012-04-17
    • 1970-01-01
    • 2012-04-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-14
    • 2019-02-17
    • 1970-01-01
    相关资源
    最近更新 更多