Youtube ID видео с URL - цель C
У меня в основном есть Youtube-url как NSString, но мне нужно извлечь идентификатор видео, отображаемый в URL-адресе. Я нашел много учебников о том, как это сделать на php или других языках программирования на основе Интернета, но ни один из них в объективном c...
Я в основном ищу метод, который запрашивает URL-адрес NSString в качестве параметра и возвращает идентификатор видео в качестве другой nsstring...
Кто-нибудь знает, как это сделать или какие-либо учебники там?
Ответы
Ответ 1
Таким образом, URL-адрес YouTube выглядит примерно так:
http://www.youtube.com/watch?v=oHg5SJYRHA0
Идентификатор видео, который вас интересует, - это часть в конце (oHg5SJYRHA0
).... хотя это не обязательно в конце, так как URL-адреса YouTube могут содержать другие параметры в строке запроса.
Лучше всего, вероятно, использовать регулярное выражение и Foundation NSRegularExpression
. Я предполагаю, что этот подход используется в других учебниках, которые вы нашли, - обратите внимание, что содержание регулярных выражений практически одинаково на любом языке или наборе инструментов, который включает их, поэтому любое регулярное выражение, найденное в этих учебниках, должно работать для тебя. (Я бы посоветовал вам не подходить к v=
и принимать ровно 11 символов, поскольку это подвержено различным режимам отказа, к которым регулярное выражение более надежное.)
Чтобы найти идентификатор видео, вам может понадобиться регулярное выражение, например v=([^&]+)
. v=
возвращает нас в нужную часть URL-адреса запроса (если мы получим что-то вроде watch?fmt=22&v=oHg5SJYRHA0
). Скобки создают группу захвата, поэтому мы можем извлекать только идентификатор видео, а не другие совпадающие символы, которые мы использовали для его поиска, а внутри круглых скобок мы ищем последовательность из одного или нескольких символов, которые не являются амперсандами - это гарантирует мы получаем все в поле v=whatever
и после него не будут полей, если вы получите URL-адрес, например watch?v=oHg5SJYRHA0&rel=0
.
Если вы используете это или другое регулярное выражение, вероятно, вы будете использовать группы захвата. (Если нет, rangeOfFirstMatchInString:options:range:
- это все, что вам нужно, как видно из ответа Димы.) Вы можете получить содержимое групп захвата (как NSTextCheckingResult
), используя firstMatchInString:options:range:
или аналогичные методы:
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];
}
Ответ 2
Здесь RegExp он охватывает эти случаи
![]()
Цель C
- (NSString *)extractYoutubeIdFromLink:(NSString *)link {
NSString *regexString = @"((?<=(v|V)/)|(?<=be/)|(?<=(\\?|\\&)v=)|(?<=embed/))([\\w-]++)";
NSRegularExpression *regExp = [NSRegularExpression regularExpressionWithPattern:regexString
options:NSRegularExpressionCaseInsensitive
error:nil];
NSArray *array = [regExp matchesInString:link options:0 range:NSMakeRange(0,link.length)];
if (array.count > 0) {
NSTextCheckingResult *result = array.firstObject;
return [link substringWithRange:result.range];
}
return nil;
}
Свифта
func extractYoutubeIdFromLink(link: String) -> String? {
let pattern = "((?<=(v|V)/)|(?<=be/)|(?<=(\\?|\\&)v=)|(?<=embed/))([\\w-]++)"
guard let regExp = try? NSRegularExpression(pattern: pattern, options: .CaseInsensitive) else {
return nil
}
let nsLink = link as NSString
let options = NSMatchingOptions(rawValue: 0)
let range = NSRange(location: 0,length: nsLink.length)
let matches = regExp.matchesInString(link as String, options:options, range:range)
if let firstMatch = matches.first {
return nsLink.substringWithRange(firstMatch.range)
}
return nil
}
Swift 3
func extractYoutubeIdFromLink(link: String) -> String? {
let pattern = "((?<=(v|V)/)|(?<=be/)|(?<=(\\?|\\&)v=)|(?<=embed/))([\\w-]++)"
guard let regExp = try? NSRegularExpression(pattern: pattern, options: .caseInsensitive) else {
return nil
}
let nsLink = link as NSString
let options = NSRegularExpression.MatchingOptions(rawValue: 0)
let range = NSRange(location: 0, length: nsLink.length)
let matches = regExp.matches(in: link as String, options:options, range:range)
if let firstMatch = matches.first {
return nsLink.substring(with: firstMatch.range)
}
return nil
}
Ответ 3
Извините - у меня недостаточно комментариев, чтобы добавить комментарий к выбранному ответу.
Проведя возраст, пытаясь найти правильный синтаксис для регулярного выражения, я столкнулся с этим, что помогло мне. Надеюсь, это может помочь кому-то еще!
NSString *regexString = @"(?<=v(=|/))([-a-zA-Z0-9_]+)|(?<=youtu.be/)([-a-zA-Z0-9_]+)";
Взято из здесь. Это работает для следующих форматов URL:
Ответ 4
Уроки, которые вы, вероятно, видите, - это просто инструкции по использованию регулярных выражений, которые также вы хотите использовать в этом случае.
Класс Cocoa, который вам нужно использовать, это NSRegularExpression.
Ваша фактическая строка регулярного выражения будет зависеть от формата, который вы ожидаете от URL-адреса, поскольку он похож на то, что у youtube есть несколько. Общая функция будет выглядеть примерно так:
+ (NSString *)extractYoutubeID:(NSString *)youtubeURL
{
NSError *error = NULL;
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@"your regex string goes here" options:NSRegularExpressionCaseInsensitive error:&error];
NSRange rangeOfFirstMatch = [regex rangeOfFirstMatchInString:youtubeURL options:0 range:NSMakeRange(0, [youtubeURL length])];
if(!NSEqualRanges(rangeOfFirstMatch, NSMakeRange(NSNotFound, 0)))
{
NSString *substringForFirstMatch = [youtubeURL substringWithRange:rangeOfFirstMatch];
return substringForFirstMatch;
}
return nil;
}
Ответ 5
Вам даже не нужны регулярные выражения. Следующие действия выполняются независимо от длины идентификатора видео и его позиции в URL-адресе:
NSString *vID = nil;
NSString *url = @"http://www.youtube.com/watch?v=cAcqdjLCN7s";
NSString *query = [url componentsSeparatedByString:@"?"][1];
NSArray *pairs = [query componentsSeparatedByString:@"&"];
for (NSString *pair in pairs) {
NSArray *kv = [pair componentsSeparatedByString:@"="];
if ([kv[0] isEqualToString:@"v"]) {
vID = kv[1];
break;
}
}
NSLog(@"%@", vID);
Ответ 6
На основе этого ответа: PHP Regex получит идентификатор видео youtube?
Я адаптировал регулярное выражение для строки c/objc/С++, важная часть здесь заключается в том, что регулярное выражение не получает видеоролики из facebook или других сервисов.
iOS regex основан на: ICU
NSString *regexString = @"^(?:http(?:s)?://)?(?:www\\.)?(?:m\\.)?(?:youtu\\.be/|youtube\\.com/(?:(?:watch)?\\?(?:.*&)?v(?:i)?=|(?:embed|v|vi|user)/))([^\?&\"'>]+)";
NSError *error;
NSRegularExpression *regex =
[NSRegularExpression regularExpressionWithPattern:regexString
options:NSRegularExpressionCaseInsensitive
error:&error];
NSTextCheckingResult *match = [regex firstMatchInString:message
options:0
range:NSMakeRange(0, [message length])];
if (match && match.numberOfRanges == 2) {
NSRange videoIDRange = [match rangeAtIndex:1];
NSString *videoID = [message substringWithRange:videoIDRange];
return videoID;
}
Матчи:
Не соответствует:
Ответ 7
- (NSString*)getYoutubeVideoID:(NSString*)url {
NSError *error = NULL;
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@"(?<=watch\\?v=|/videos/|embed\\/)[^#\\&\\?]*"
options:NSRegularExpressionCaseInsensitive
error:&error];
NSTextCheckingResult *match = [regex firstMatchInString:url
options:0
range:NSMakeRange(0, [url length])];
NSString *substringForFirstMatch;
if (match) {
NSRange videoIDRange = [match rangeAtIndex:0];
substringForFirstMatch = [url substringWithRange:videoIDRange];
}
return substringForFirstMatch;
}
Ответ 8
Я использовал самый высокий голосовой ответ для написания лучшего, более ограничивающего регулярного выражения.
NSString *regex = @"(?:youtube.com.+v[=/]|youtu.be/)([-a-zA-Z0-9_]+)";
а затем вы можете получить идентификатор
NSTextCheckingResult *match = [regex firstMatchInString:url
options:0
range:NSMakeRange(0, [url length])];
NSRange videoIDRange = [match rangeAtIndex:1];
NSString *youTubeID = [url substringWithRange:videoIDRange];
Ответ 9
Вот мое решение, которое ссылается на StackOveFlow. (Youtube I.D синтаксический анализ для новых форматов URL)
Я сделал некоторые изменения.
///Это .h
#import <Foundation/Foundation.h>
@interface YoutubeParser : NSObject
+(BOOL) isValidateYoutubeURL:(NSString * )youtubeURL;
+(NSArray *) parseHTML:(NSString *)html ;
@end
///This is the .m
#import "YoutubeParser.h"
@interface YoutubeParser () {
}
@end
@implementation YoutubeParser
#define YOUTUBE_PATTERN @"(https?://)?(www\\.)?(youtu\\.be/|youtube\\.com)?(/|/embed/|/v/|/watch\\?v=|/watch\\?.+&v=)([\\w_-]{11})(&.+)?"
+(NSRegularExpression *)regex {
static NSRegularExpression * regex = nil;
regex = [NSRegularExpression regularExpressionWithPattern:YOUTUBE_PATTERN
options:NSRegularExpressionCaseInsensitive
error:nil];
return regex;
}
+(BOOL) isValidateYoutubeURL:(NSString * )youtubeURL {
NSInteger cnt = [[YoutubeParser regex] numberOfMatchesInString:youtubeURL options:0 range:NSMakeRange(0, [youtubeURL length]) ];
return cnt > 0 ? YES : NO;
}
typedef void (^matching_block_t) (NSTextCheckingResult *result, NSMatchingFlags flags, BOOL *stop);
+(NSArray *) parseHTML:(NSString *)html {
NSMutableArray * youtubeURLArray = [[NSMutableArray alloc] init];
matching_block_t parseTask = ^(NSTextCheckingResult *result, NSMatchingFlags flags, BOOL *stop) {
NSRange matchRange = [result range];
NSRange youtubeKey = [result rangeAtIndex:5]; //the youtube key
NSString * strKey = [html substringWithRange:youtubeKey] ;
NSLog(@"youtubeKey=%@ , with url=%@ " ,strKey , [html substringWithRange:matchRange]);
[youtubeURLArray addObject:strKey];
};
[[YoutubeParser regex] enumerateMatchesInString:html options:0 range:NSMakeRange(0, [html length]) usingBlock:parseTask ];
return youtubeURLArray;
}
@end
Ответ 10
Здесь есть много хороших ответов, но я подумал, что некоторым может быть полезно проанализировать несколько строк video_ID. Это может быть веб-страница или массив разных URL-адресов.
Пример содержимого страницы
NSString *content = @"http://www.youtube.com/user/Scobleizer#p/u/1/1p3vcRhsYGo,http://youtu.be/NLqAF9hrVbY,http://www.youtube.com/watch?v=NLqAF9hrVbY,http://facebook.com,http://www.youtube.com/watch?v=cAcqdjLCN7s";
Метод
-(NSArray *)extractVideos:(NSString *)content {
NSString *extractRegex = @"(?<=v(=|/))([-a-zA-Z0-9_]+)|(?<=youtu.be/)([-a-zA-Z0-9_]+)"
NSMutableArray *extractedContent = [[NSMutableArray alloc] init];
if ([content hasPrefix:@"http://"] || [content hasPrefix:@"https://"]) {
NSURL *extractURL = [NSURL URLWithString:content];
if ([extractURL.host rangeOfString:@"youtu"].location != NSNotFound) {
NSRegularExpression *extractRegex = [NSRegularExpression regularExpressionWithPattern:extractRegex options:NSRegularExpressionCaseInsensitive error:nil];
NSArray *extractResults = [extractRegex matchesInString:content options:0 range:NSMakeRange(0, content.length)];
for (NSTextCheckingResult *match in extractResults) {
[extractedContent addObject:[content substringWithRange:match.range]];
}
}
}
return extractedContent;
}
Выход
(
NLqAF9hrVbY,
QLqAF9eeVbY,
cAcqdjLCN7s
)
Кредит @Alex для регулярного выражения
Ответ 11
Объединив некоторые ваши ответы, я бы сказал, что это лучший ответ:
+ (NSString *)extractYoutubeID:(NSString *)youtubeURL
{
NSError *error = NULL;
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@"(?<=v(=|/))([-a-zA-Z0-9_]+)|(?<=youtu.be/)([-a-zA-Z0-9_]+)"
options:NSRegularExpressionCaseInsensitive
error:&error];
NSRange rangeOfFirstMatch = [regex rangeOfFirstMatchInString:youtubeURL options:NSMatchingReportProgress range:NSMakeRange(0, [youtubeURL length])];
if(rangeOfFirstMatch.location != NSNotFound) {
NSString *substringForFirstMatch = [youtubeURL substringWithRange:rangeOfFirstMatch];
return substringForFirstMatch;
}
return nil;
}
Ответ 12
версия Swift 2 для ответа @Alex
func getYoutubeVideoId(youtubeLink:String) -> String?{
var youtubeId:String? = nil
let pattern: String = "((?<=(v|V)/)|(?<=be/)|(?<=(\\?|\\&)v=)|(?<=embed/))([\\w-]++)"
do {
let regex = try NSRegularExpression(pattern: pattern, options: .CaseInsensitive)
if let regexMatch = regex.firstMatchInString(youtubeLink, options: NSMatchingOptions(rawValue: 0), range: NSRange(location: 0, length: youtubeLink.characters.count)) {
youtubeId = (youtubeLink as NSString).substringWithRange(regexMatch.range)
}
}
catch let error as NSError{
print("Error while extracting youtube id \(error.debugDescription)")
}
return youtubeId
}
Ответ 13
Обновить Swift 4:
static func extractYoutubeVideoId(from url: String) -> String? {
let pattern = "((?<=(v|V)/)|(?<=be/)|(?<=(\\?|\\&)v=)|(?<=embed/))([\\w-]++)"
guard let range = url.range(of: pattern, options: .regularExpression) else { return nil }
return String(url[range])
}
Старый ответ:
Немного более быстрый способ @Alex Swift 3 ответа без использования NSString:
Мы можем заставить попробовать регулярное выражение, потому что мы знаем, что оно действительно.
static func extractYoutubeVideoId(from url: String) -> String? {
let pattern = "((?<=(v|V)/)|(?<=be/)|(?<=(\\?|\\&)v=)|(?<=embed/))([\\w-]++)"
let regex = try! NSRegularExpression(pattern: pattern, options: [.caseInsensitive])
let range = NSRange(location: 0, length: url.utf16.count)
guard let firstMatch = regex.firstMatch(in: url, options: .init(rawValue: 0), range: range) else { return nil }
let start = String.UTF16Index(firstMatch.range.location)
let end = String.UTF16Index(firstMatch.range.location + firstMatch.range.length)
return String(url.utf16[start..<end])
}
Или, если вы все еще хотите NSString:
static func extractYoutubeVideoId(from url: String) -> String? {
let pattern = "((?<=(v|V)/)|(?<=be/)|(?<=(\\?|\\&)v=)|(?<=embed/))([\\w-]++)"
let regex = try! NSRegularExpression(pattern: pattern, options: [.caseInsensitive])
let range = NSRange(location: 0, length: (url as NSString).length)
guard let firstMatch = regex.firstMatch(in: url, options: .init(rawValue: 0), range: range) else { return nil }
return (url as NSString).substring(with: firstMatch.range)
}
Ответ 14
Вот быстрая версия с использованием @jt_ik regex:
func extractYoutubeID(youtubeURL: String) -> String {
var error: NSError?
let pattern: String = "(?<=v(=|/))([-a-zA-Z0-9_]+)|(?<=youtu.be/)([-a-zA-Z0-9_]+)"
let regex = NSRegularExpression(pattern: pattern, options: .CaseInsensitive, error: &error)!
if error == nil {
if let regexMatch = regex.firstMatchInString(youtubeURL, options: nil, range: NSRange(location: 0, length: youtubeURL.utf16Count)) {
return (youtubeURL as NSString).substringWithRange(regexMatch.range)
}
// Handle no match here
return ""
} else {
// Handle error here
println(error?.userInfo)
return ""
}
}
Ответ 15
версия Swift 3 для ответа @Alex
func extractYoutubeIdFromLink(link: String) -> String? {
let pattern = "((?<=(v|V)/)|(?<=be/)|(?<=(\\?|\\&)v=)|(?<=embed/))([\\w-]++)"
guard let regExp = try? NSRegularExpression(pattern: pattern, options: .caseInsensitive) else {
return nil
}
let nsLink = link as NSString
let options = NSRegularExpression.MatchingOptions(rawValue: 0)
let range = NSRange(location: 0,length: nsLink.length)
let matches = regExp.matches(in: link as String, options:options, range:range)
if let firstMatch = matches.first {
debugPrint(firstMatch)
return nsLink.substring(with: firstMatch.range)
}
return nil
}
Ответ 16
Я понял это сам...
NSArray *videoURLSplit = [videoURL componentsSeparatedByString:@"v="];
NSString *videoID = [[videoURLSplit objectAtIndex:1] substringToIndex:11];
NSLog(@"%@",videoID);
Очень просто... Все видеоролики содержат v = VIDEO_ID Я просто отделил URL-адрес в массив, а затем взял первые 11 цифр того, что после v =, поскольку в URL-адресе может быть больше информации HTTP GET...
Спасибо за помощь, хотя!