在没有方案的情况下验证 URL
Validate URL without scheme
Swift5,Xcode10,iOS12
我的代码使用 UIApplication.shared.canOpenURL
来验证 URL,不幸的是,没有例如"http://".
示例:
print(UIApplication.shared.canOpenURL(URL(string: "whosebug.com")!)) //false
print(UIApplication.shared.canOpenURL(URL(string: "http://whosebug.com")!)) //true
print(UIApplication.shared.canOpenURL(URL(string: "129.0.0.1")!)) //false
print(UIApplication.shared.canOpenURL(URL(string: "ftp://129.0.0.1")!)) //true
我知道 schemes (iOS9+) 的变化,我知道如果字符串没有开始,我可以添加像 "http://" 这样的前缀已经有了它,然后检查这个新字符串,但我仍然想知道:
问题: 我如何添加 "there's no scheme" 方案,这样有效的 URL 也像 "whosebug.com" return true
(这甚至可能吗?)?
这是我使用的方法
extension String {
/// Return first available URL in the string else nil
func checkForURL() -> NSRange? {
guard let detector = try? NSDataDetector(types: NSTextCheckingResult.CheckingType.link.rawValue) else {
return nil
}
let matches = detector.matches(in: self, options: [], range: NSRange(location: 0, length: self.utf16.count))
for match in matches {
guard Range(match.range, in: self) != nil else { continue }
return match.range
}
return nil
}
func getURLIfPresent() -> String? {
guard let range = self.checkForURL() else{
return nil
}
guard let stringRange = Range(range,in:self) else {
return nil
}
return String(self[stringRange])
}
}
显然,方法名和代码中的注释不够冗长,所以这里解释一下。
已使用 NSDataDetector and provided it the type - NSTextCheckingResult.CheckingType.link 检查 link 秒。
这遍历提供的字符串和 return 的 URL 类型的所有匹配项。
这将检查您提供的字符串中的 link,如果有的话,否则 returns nil。
方法 getURLIfPresent return 该字符串的 URL 部分。
这里有几个例子
print("http://whosebug.com".getURLIfPresent())
print("whosebug.com".getURLIfPresent())
print("ftp://127.0.0.1".getURLIfPresent())
print("www.google.com".getURLIfPresent())
print("127.0.0.1".getURLIfPresent())
print("127".getURLIfPresent())
print("hello".getURLIfPresent())
Output
Optional("http://whosebug.com")
Optional("whosebug.com")
Optional("ftp://127.0.0.1")
Optional("www.google.com")
nil
nil
nil
但是,对于“127.0.0.1”,这 return 并不成立。所以我不认为它会实现你的事业。
就您而言,采用正则表达式的方式似乎更好。如果您遇到更多需要被视为 URL.
的模式,您可以添加更多条件
无法向 URL
添加有效方案,因为没有人知道哪个前缀将添加到哪个 URL
。您可以在 regex
.
的帮助下验证 URL
我搜索并修改了正则表达式。
extension String {
func isValidUrl() -> Bool {
let regex = "((http|https|ftp)://)?((\w)*|([0-9]*)|([-|_])*)+([\.|/]((\w)*|([0-9]*)|([-|_])*))+"
let predicate = NSPredicate(format: "SELF MATCHES %@", regex)
return predicate.evaluate(with: self)
}
}
我用下面的网址测试了它:
print("http://whosebug.com".isValidUrl())
print("whosebug.com".isValidUrl())
print("ftp://127.0.0.1".isValidUrl())
print("www.google.com".isValidUrl())
print("127.0.0.1".isValidUrl())
print("127".isValidUrl())
print("hello".isValidUrl())
Output
true
true
true
true
true
false
false
注意: 100% 正则表达式无法验证 email
和 url
Swift5,Xcode10,iOS12
我的代码使用 UIApplication.shared.canOpenURL
来验证 URL,不幸的是,没有例如"http://".
示例:
print(UIApplication.shared.canOpenURL(URL(string: "whosebug.com")!)) //false
print(UIApplication.shared.canOpenURL(URL(string: "http://whosebug.com")!)) //true
print(UIApplication.shared.canOpenURL(URL(string: "129.0.0.1")!)) //false
print(UIApplication.shared.canOpenURL(URL(string: "ftp://129.0.0.1")!)) //true
我知道 schemes (iOS9+) 的变化,我知道如果字符串没有开始,我可以添加像 "http://" 这样的前缀已经有了它,然后检查这个新字符串,但我仍然想知道:
问题: 我如何添加 "there's no scheme" 方案,这样有效的 URL 也像 "whosebug.com" return true
(这甚至可能吗?)?
这是我使用的方法
extension String {
/// Return first available URL in the string else nil
func checkForURL() -> NSRange? {
guard let detector = try? NSDataDetector(types: NSTextCheckingResult.CheckingType.link.rawValue) else {
return nil
}
let matches = detector.matches(in: self, options: [], range: NSRange(location: 0, length: self.utf16.count))
for match in matches {
guard Range(match.range, in: self) != nil else { continue }
return match.range
}
return nil
}
func getURLIfPresent() -> String? {
guard let range = self.checkForURL() else{
return nil
}
guard let stringRange = Range(range,in:self) else {
return nil
}
return String(self[stringRange])
}
}
显然,方法名和代码中的注释不够冗长,所以这里解释一下。
已使用 NSDataDetector and provided it the type - NSTextCheckingResult.CheckingType.link 检查 link 秒。
这遍历提供的字符串和 return 的 URL 类型的所有匹配项。
这将检查您提供的字符串中的 link,如果有的话,否则 returns nil。
方法 getURLIfPresent return 该字符串的 URL 部分。
这里有几个例子
print("http://whosebug.com".getURLIfPresent())
print("whosebug.com".getURLIfPresent())
print("ftp://127.0.0.1".getURLIfPresent())
print("www.google.com".getURLIfPresent())
print("127.0.0.1".getURLIfPresent())
print("127".getURLIfPresent())
print("hello".getURLIfPresent())
Output
Optional("http://whosebug.com")
Optional("whosebug.com")
Optional("ftp://127.0.0.1")
Optional("www.google.com")
nil
nil
nil
但是,对于“127.0.0.1”,这 return 并不成立。所以我不认为它会实现你的事业。 就您而言,采用正则表达式的方式似乎更好。如果您遇到更多需要被视为 URL.
的模式,您可以添加更多条件无法向 URL
添加有效方案,因为没有人知道哪个前缀将添加到哪个 URL
。您可以在 regex
.
URL
我搜索并修改了正则表达式。
extension String {
func isValidUrl() -> Bool {
let regex = "((http|https|ftp)://)?((\w)*|([0-9]*)|([-|_])*)+([\.|/]((\w)*|([0-9]*)|([-|_])*))+"
let predicate = NSPredicate(format: "SELF MATCHES %@", regex)
return predicate.evaluate(with: self)
}
}
我用下面的网址测试了它:
print("http://whosebug.com".isValidUrl())
print("whosebug.com".isValidUrl())
print("ftp://127.0.0.1".isValidUrl())
print("www.google.com".isValidUrl())
print("127.0.0.1".isValidUrl())
print("127".isValidUrl())
print("hello".isValidUrl())
Output
true
true
true
true
true
false
false
注意: 100% 正则表达式无法验证 email
和 url