我有一个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!")
}
}
一些示例输出:
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!
我做错了吗?
答案 0 :(得分:25)
检查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;
}
答案 1 :(得分:9)
NSURL.URLWithString
根据解释这些不那么可读的文档中列出的相对或绝对地址的条件,评估您传递的URL字符串:RFC 2396,{{3 }和1738。也就是说,您希望验证的内容只是NSURL
可以处理的一小部分。您最好使用RegEx或两个,可能来自1808:
@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")
}
}
答案 2 :(得分:1)
来自@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() }
}
用法:
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
答案 3 :(得分:1)
已基于@Nate Cook
response更新为 Swift 5.1 。
@IBAction func verifyTarget(sender: NSTextFieldCell) {
guard let strRawTarget = sender.stringValue else { print("no input!"); return }
print("Input: " + strRawTarget)
if strRawTarget.isValidIpAddress {
print("\(strRawTarget) is a valid IP address")
} else if strRawTarget.isValidHostname {
print("\(strRawTarget) is a valid hostname")
} else {
print("\(strRawTarget) is not valid")
}
}
struct Regex {
private init() {}
static let ipAddress = "^(([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])$"
static let hostname = "^(([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])$"
}
extension String {
var isValidIpAddress: Bool {
return self.matches(pattern: Regex.ipAddress)
}
var isValidHostname: Bool {
return self.matches(pattern: Regex.hostname)
}
private func matches(pattern: String) -> Bool {
return self.range(of: pattern,
options: .regularExpression,
range: nil,
locale: nil) != nil
}
}
答案 4 :(得分:0)
@IBAction func verifyTarget(sender: NSTextFieldCell) -> Bool {
let validIP = "^(([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])$"
if ((sender.stringValue.count == 0) || (sender.stringValue!.range(of: validIP, options: .regularExpression) == nil)) {
return false
}
return true
}
答案 5 :(得分:0)
新的网络框架为struct IPv4Address和struct IPv6Address提供了失败的初始化程序,它们很容易处理IP地址部分。使用所有正则表达式,使用正则表达式在IPv6中执行此操作都很困难。
很遗憾,我无法处理域名部分。
请注意,网络框架是最新的,因此可能会迫使您为最新的OS版本进行编译。
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"