问题
Basically I have a Youtube URL as string, I want to extract the video Id from that URL. I found some code in objective c that is as below:
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];
}
When I am converting this code to swift3 that is:
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)
}
Gives error as:
fatal error: 'try!' expression unexpectedly raised an error: Error Domain=NSCocoaErrorDomain Code=2048 "The value “?.*v=([^&]+)” is invalid."
Can anybody help me about this error or anybody explain how to get video id from url in Swift 3.
Thanks in advance
回答1:
I have a different way of doing this using URLComponents. You then just select the 'v' parameter from the url, if it exists.
func getYoutubeId(youtubeUrl: String) -> String? {
return URLComponents(string: youtubeUrl)?.queryItems?.first(where: { $0.name == "v" })?.value
}
And then pass in a Youtube url like this:
print (getYoutubeId(youtubeUrl: "https://www.youtube.com/watch?v=Y7ojcTR78qE&spfreload=9"))
回答2:
Safer version (without force unwrapping !
):
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)
}
}
Examples:
"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"
Credits: Usman Nisar's answer
回答3:
Here is code to extract youtube video id from any youtube url: (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 ""
}
回答4:
A Swift 4 version using the elegant flatMap
:
func extractYouTubeId(from url: String) -> String? {
let typePattern = "(?:(?:\\.be\\/|embed\\/|v\\/|\\?v=|\\&v=|\\/videos\\/)|(?:[\\w+]+#\\w\\/\\w(?:\\/[\\w]+)?\\/\\w\\/))([\\w-_]+)"
let regex = try? NSRegularExpression(pattern: typePattern, options: .caseInsensitive)
return regex
.flatMap { $0.firstMatch(in: url, range: NSMakeRange(0, url.count)) }
.flatMap { Range($0.range(at: 1), in: url) }
.map { String(url[$0]) }
}
This method uses a regex that detects most of the possible YouTube URL formats (.be/*
, /embed/
, /v/
- you can find the full list here).
回答5:
Your first problem is you are not escaping ?
in your expression. ?
is reserved character and if you want to use it in your expressions, you must escape with \
and since \
is used also to escape "
character you must escape ?
with double backslash something like \\?
. So according to above information, following code correctly extracts the videoId
let youtubeURL = "https://www.youtube.com/watch?v=uH8o-JTHJdM"
let regex = try! NSRegularExpression(pattern: "\\?.*v=([^&]+)", options: .caseInsensitive)
let match = regex.firstMatch(in: youtubeURL, options: [], range: NSRange(location: 0, length: youtubeURL.characters.count))
if let videoIDRange = match?.rangeAt(1) {
let substringForFirstMatch = (youtubeURL as NSString).substring(with: videoIDRange)
} else {
//NO video URL
}
回答6:
To get video Id from Youtube Url, use code # Swift4 :
var videoId = ""
if youtubeLink.lowercased().contains("youtu.be"){
linkString = youtubeLink
if let range = linkString.range(of: "be/"){
videoId = youtubeLink[range.upperBound...].trimmingCharacters(in: .whitespaces)
}
}
else if youtubeLink.lowercased().contains("youtube.com"){
linkString = youtubeLink
if let range = linkString.range(of: "?v="){
videoId = youtubeLink[range.upperBound...].trimmingCharacters(in: .whitespaces)
}
}
Hope will be helping! :)
来源:https://stackoverflow.com/questions/41166092/youtube-video-id-from-url-swift3