Sus*_*ahu 5 regex nsregularexpression swift swift3
基本上我有一个Youtube URL作为字符串,我想从该URL中提取视频ID.我发现目标c中的一些代码如下:
NSError *error = NULL;
NSRegularExpression *regex =
[NSRegularExpression regularExpressionWithPattern:@"?.*v=([^&]+)"
options:NSRegularExpressionCaseInsensitive
error:&error];
NSTextCheckingResult *match = [regex firstMatchInString:youtubeURL
options:0
range:NSMakeRange(0, [youtubeURL length])];
if (match) {
NSRange videoIDRange = [match rangeAtIndex:1];
NSString *substringForFirstMatch = [youtubeURL substringWithRange:videoIDRange];
}
Run Code Online (Sandbox Code Playgroud)
当我将此代码转换为swift3时,它是:
var error: Error? = nil
var regex = try! NSRegularExpression(pattern: "?.*v=([^&]+)", options: .caseInsensitive)
var match = regex!.firstMatch(in: youtubeURL, options: [], range: NSRange(location: 0, length: youtubeURL.length))!
if match {
var videoIDRange = match.rangeAt(1)
var substringForFirstMatch = (youtubeURL as NSString).substring(with: videoIDRange)
}
Run Code Online (Sandbox Code Playgroud)
给出错误:
致命错误:'试试!' 表达式意外地引发了错误:错误Domain = NSCocoaErrorDomain Code = 2048"值"?.*v =([^&] +)"无效."
任何人都可以帮我解决这个错误,或者任何人解释如何从Swift 3中的url获取视频ID.
提前致谢
Isl*_* Q. 24
Swift 3/4准备好且更安全版本(无需强行展开!):
extension String {
var youtubeID: String? {
let pattern = "((?<=(v|V)/)|(?<=be/)|(?<=(\\?|\\&)v=)|(?<=embed/))([\\w-]++)"
let regex = try? NSRegularExpression(pattern: pattern, options: .caseInsensitive)
let range = NSRange(location: 0, length: count)
guard let result = regex?.firstMatch(in: self, range: range) else {
return nil
}
return (self as NSString).substring(with: result.range)
}
}
Run Code Online (Sandbox Code Playgroud)
例子:
"https://www.youtube.com/watch?v=C0DPdy98e4c".youtubeID // "C0DPdy98e4c"
"https://youtube.com/watch?v=C0DPdy98e4c".youtubeID // "C0DPdy98e4c"
"www.youtube.com/watch?v=C0DPdy98e4c".youtubeID // "C0DPdy98e4c"
"youtube.com/watch?v=C0DPdy98e4c".youtubeID // "C0DPdy98e4c"
"https://youtu.be/C0DPdy98e4c".youtubeID // "C0DPdy98e4c"
"youtu.be/C0DPdy98e4c".youtubeID // "C0DPdy98e4c"
Run Code Online (Sandbox Code Playgroud)
tot*_*tiG 16
我使用URLComponents有不同的方法.然后,您只需从URL中选择"v"参数(如果存在).
func getYoutubeId(youtubeUrl: String) -> String? {
return URLComponents(string: youtubeUrl)?.queryItems?.first(where: { $0.name == "v" })?.value
}
Run Code Online (Sandbox Code Playgroud)
然后传入Youtube网址:
print (getYoutubeId(youtubeUrl: "https://www.youtube.com/watch?v=Y7ojcTR78qE&spfreload=9"))
Run Code Online (Sandbox Code Playgroud)
雨燕5
var youtubeURLs = [
"http://www.youtube.com/watch?v=-wtIMTCHWuI",
"http://www.youtube.com/v/-wtIMTCHWuI?version=3&autohide=1",
"http://youtu.be/-wtIMTCHWuI",
"http://www.youtube.com/oembed?url=http%3A//www.youtube.com/watch?v%3D-wtIMTCHWuI&format=json",
"https://youtu.be/uJ2PZaO1N5E",
"https://www.youtube.com/embed/M7lc1UVf-VE",
"http://www.youtube.com/attribution_link?a=JdfC0C9V6ZI&u=%2Fwatch%3Fv%3DEhxJLojIE_o%26feature%3Dshare",
"https://www.youtube.com/attribution_link?a=8g8kPrPIi-ecwIsS&u=/watch%3Fv%3DyZv2daTWRZU%26feature%3Dem-uploademail"
]
func getVideoID(from urlString: String) -> String? {
guard let url = urlString.removingPercentEncoding else { return nil }
do {
let regex = try NSRegularExpression.init(pattern: "((?<=(v|V)/)|(?<=be/)|(?<=(\\?|\\&)v=)|(?<=embed/))([\\w-]++)", options: .caseInsensitive)
let range = NSRange(location: 0, length: url.count)
if let matchRange = regex.firstMatch(in: url, options: .reportCompletion, range: range)?.range {
let matchLength = (matchRange.lowerBound + matchRange.length) - 1
if range.contains(matchRange.lowerBound) &&
range.contains(matchLength) {
let start = url.index(url.startIndex, offsetBy: matchRange.lowerBound)
let end = url.index(url.startIndex, offsetBy: matchLength)
return String(url[start...end])
}
}
} catch {
print(error.localizedDescription)
}
return nil
}
for url in youtubeURLs {
print("Video id: \(getVideoID(from: url) ?? "NA") for url: \(url)")
}
Run Code Online (Sandbox Code Playgroud)
结果:
Video id: -wtIMTCHWuI for url: http://www.youtube.com/watch?v=-wtIMTCHWuI
Video id: -wtIMTCHWuI for url: http://www.youtube.com/v/-wtIMTCHWuI?version=3&autohide=1
Video id: -wtIMTCHWuI for url: http://youtu.be/-wtIMTCHWuI
Video id: -wtIMTCHWuI for url: http://www.youtube.com/oembed?url=http%3A//www.youtube.com/watch?v%3D-wtIMTCHWuI&format=json
Video id: uJ2PZaO1N5E for url: https://youtu.be/uJ2PZaO1N5E
Video id: M7lc1UVf-VE for url: https://www.youtube.com/embed/M7lc1UVf-VE
Video id: EhxJLojIE_o for url: http://www.youtube.com/attribution_link?a=JdfC0C9V6ZI&u=%2Fwatch%3Fv%3DEhxJLojIE_o%26feature%3Dshare
Video id: yZv2daTWRZU for url: https://www.youtube.com/attribution_link?a=8g8kPrPIi-ecwIsS&u=/watch%3Fv%3DyZv2daTWRZU%26feature%3Dem-uploademail
Run Code Online (Sandbox Code Playgroud)
这是从任何 youtube 网址中提取 youtube 视频 ID 的代码:(Swift)
func extractYoutubeId(fromLink link: String) -> String {
let regexString: String = "((?<=(v|V)/)|(?<=be/)|(?<=(\\?|\\&)v=)|(?<=embed/))([\\w-]++)"
let regExp = try? NSRegularExpression(pattern: regexString, options: .caseInsensitive)
let array: [Any] = (regExp?.matches(in: link, options: [], range: NSRange(location: 0, length: (link.characters.count ))))!
if array.count > 0 {
let result: NSTextCheckingResult? = array.first as? NSTextCheckingResult
return (link as NSString).substring(with: (result?.range)!)
}
return ""
}
Run Code Online (Sandbox Code Playgroud)