验证NSTextField中的字符串是否为有效的IP地址或域名

Mat*_*att 6 string validation macos parsing swift

我有一个NSTextField地方,我要求用户输入一个IPv4格式的字符串,或域名,如www.example.com.目前,我的代码是:

@IBAction func verifyTarget(sender: NSTextFieldCell) {
    var txtTarget: NSTextFieldCell = sender

    var strRawTarget: String? = txtTarget.stringValue
    println("Input: " + strRawTarget!)
    var URLTarget: NSURL?

    URLTarget = NSURL.URLWithString(strRawTarget)
    if URLTarget {
        println("URL \(URLTarget) is valid!")
    }
    else {
        println("URL \(strRawTarget) is not valid!")
    }
}
Run Code Online (Sandbox Code Playgroud)

一些示例输出:

Input: 
URL  is valid!
Input: adsfasdf
URL adsfasdf is valid!
Input: afe12389hfs. . afopadsf
URL afe12389hfs. . afopadsf is not valid!
Input: 192.292.111.3
URL 192.292.111.3 is valid!
Input: 0.a.0.a
URL 0.a.0.a is valid!
Input: %2
URL %2 is not valid!
Input: %20
URL %20 is valid!
Run Code Online (Sandbox Code Playgroud)

难道我做错了什么?

小智 26

检查Swift中的IP地址是IPv4还是IPv6

func validateIpAddress(ipToValidate: String) -> Bool {

    var sin = sockaddr_in()
    var sin6 = sockaddr_in6()

    if ipToValidate.withCString({ cstring in inet_pton(AF_INET6, cstring, &sin6.sin6_addr) }) == 1 {
        // IPv6 peer.
        return true
    }
    else if ipToValidate.withCString({ cstring in inet_pton(AF_INET, cstring, &sin.sin_addr) }) == 1 {
        // IPv4 peer.
        return true
    }

    return false;
}
Run Code Online (Sandbox Code Playgroud)


Nat*_*ook 9

NSURL.URLWithString评估你通过它基于对在这些未全是可读的文件中规定了解码的相对或绝对地址的标准URL字符串:的RFC 2396,17381808.也就是说,您希望验证的只是NSURL可以处理的一小部分.您最好使用一两个RegEx,也许可以从这个答案中得到:

@IBAction func verifyTarget(sender: NSTextFieldCell) {
    var txtTarget: NSTextFieldCell = sender

    var strRawTarget: String? = txtTarget.stringValue
    println("Input: " + strRawTarget!)

    let validIpAddressRegex = "^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$"
    let validHostnameRegex = "^(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\\-]*[a-zA-Z0-9])\\.)*([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9\\-]*[A-Za-z0-9])$"

    if strRawTarget == nil {
        println("no input!")
    } else if strRawTarget!.rangeOfString(validIpAddressRegex, options: .RegularExpressionSearch) {
        println("\(strRawTarget) is a valid IP address")
    } else if strRawTarget!.rangeOfString(validHostnameRegex, options: .RegularExpressionSearch) {
        println("\(strRawTarget) is a valid hostname")
    } else {
        println("\(strRawTarget) is not valid")
    }
}
Run Code Online (Sandbox Code Playgroud)


Dar*_*oot 5

新的网络框架具有用于 struct IPv4Address 和 struct IPv6Address 的可失败初始化程序,可以非常轻松地处理 IP 地址部分。由于所有缩短规则,在 IPv6 中使用正则表达式执行此操作非常困难。

不幸的是我无法解决域名部分。

请注意,网络框架是最新的,因此它可能会强制您针对最新的操作系统版本进行编译。

    import Network
let tests = ["192.168.4.4","fkjhwojfw","192.168.4.4.4","2620:3","2620::33"]

for test in tests {
    if let _ = IPv4Address(test) {
        debugPrint("\(test) is valid ipv4 address")
    } else if let _ = IPv6Address(test) {
        debugPrint("\(test) is valid ipv6 address")
    } else {
        debugPrint("\(test) is not a valid IP address")
    }
}

output:
"192.168.4.4 is valid ipv4 address"
"fkjhwojfw is not a valid IP address"
"192.168.4.4.4 is not a valid IP address"
"2620:3 is not a valid IP address"
"2620::33 is valid ipv6 address"
Run Code Online (Sandbox Code Playgroud)


Dar*_*der 5

来自@Alin 的代码更紧凑:

extension String {
func isIPv4() -> Bool {
    var sin = sockaddr_in()
    return self.withCString({ cstring in inet_pton(AF_INET, cstring, &sin.sin_addr) }) == 1
}

func isIPv6() -> Bool {
    var sin6 = sockaddr_in6()
    return self.withCString({ cstring in inet_pton(AF_INET6, cstring, &sin6.sin6_addr) }) == 1
}

func isIpAddress() -> Bool { return self.isIPv6() || self.isIPv4() }
}
Run Code Online (Sandbox Code Playgroud)

用法:

let ipv6 = "FE80:0000:0000:0000:0202:B3FF:FE1E:8329"
let ipv6Collapsed = "FE80::0202:B3FF:FE1E:8329"
let ipv4 = "19.117.63.126"

ipv6.isIpAddress()  //true
ipv6.isIPv6()       //true
ipv6.isIPv4()       //false

ipv6Collapsed.isIpAddress() //true
ipv6Collapsed.isIPv6()      //true
ipv6Collapsed.isIPv4()      //false

ipv4.isIpAddress()  //true
ipv4.isIPv6()       //false
ipv4.isIPv4()       //true
Run Code Online (Sandbox Code Playgroud)