Básicamente, tienen una url de Youtube, como un NSString, pero necesito extraer el id del vídeo que se muestra en la url. He encontrado muchos tutoriales sobre cómo hacer esto en php o cualquier otro basado en la web lenguajes de programación, pero ninguno en objective c…

Estoy básicamente buscando un método que pide un NSString url como parámetro y devuelve el id del vídeo como otro nsstring…

Alguien sabe cómo hacerlo o cualquier tutoriales por ahí?

  • Hay una clara formato que está usted trabajando? ¿Podría dar un ejemplo?
  • No sólo el fondo de Youtube escritorio url…
  • Usted podría proporcionar una dirección URL de ejemplo y lo ha intentado.
  • una vez que usted tiene el regexstring, ¿cómo lo uso?
InformationsquelleAutor The Man | 2012-07-16

16 Comentarios

  1. 15

    Así una URL de YouTube, se ve algo como:

    http://www.youtube.com/watch?v=oHg5SJYRHA0

    El ID del vídeo que le interesa es la parte en la final (oHg5SJYRHA0)…. aunque no necesariamente al final, como YouTube Url puede contener otros parámetros en la cadena de consulta.

    Su mejor apuesta es, probablemente, el uso de una expresión regular y la Fundación NSRegularExpression clase. Me gustaría presumir este enfoque se utiliza en la otra lengua tutoriales que he encontrado — tenga en cuenta que el contenido de las expresiones regulares es prácticamente el mismo en cualquier idioma o conjunto de herramientas que incluye a ellos, por lo que cualquier expresión regular que se encuentra en los tutoriales deben trabajar para usted. (Te aconsejo en contra de su enfoque de romper en v= y tomar exactamente 11 caracteres, ya que es propenso a los diversos modos de fallo para que una expresión regular es más robusto.)

    Para encontrar el ID del vídeo que usted puede ser que desee un regex como v=([^&]+). El v= nos lleva a la parte derecha de la URL de consulta (en el caso de que tenemos algo como watch?fmt=22&v=oHg5SJYRHA0). El paréntesis hacer un de captura de grupo que se pueden extraer sólo el ID de vídeo y el otro no coincidentes personajes que se utiliza para encontrarlo, y dentro de los paréntesis se busca una secuencia de uno o más caracteres, que no es un signo de y comercial — esto se asegura de que tengamos todo en la v=whatever campo, y no hay campos después de él si usted consigue una URL como watch?v=oHg5SJYRHA0&rel=0.

    Si usa otra expresión regular, es probable que usted va a utilizar la captura de grupos. (Si no, rangeOfFirstMatchInString:opciones:rango: es sólo acerca de todo lo que usted necesita, como se ve en la Demo de la respuesta.) Usted puede conseguir en el contenido de la captura de grupos (como NSTextCheckingResult objetos) mediante firstMatchInString:opciones:rango: o métodos similares:

    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];
    }
    • No son expresiones regulares un poco de un exceso de y no es lo suficientemente flexible para que este al mismo tiempo? Me parece todo esto simplemente horrible.
    • no funciona para mí debe quitar ? a partir de la expresión regular
    • regex llegar nil no funciona para mí.
  2. 67

    Aquí es RegExp cubre estos casos
    Vídeo de Youtube ID De la URL - Objetivo C

    Objetivo 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;
    }

    Swift

    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
    }
    • ¿Por qué no hacer que los métodos de la estática? No tiene que usar el auto…
    • es sólo un ejemplo, se está trabajando y usted puede cambiar estática o convertir a Cadena de extensión, de ti
    • todavía hay algunos casos donde esta expresión no está funcionando así que aquí está la nueva expresión regular de patrón de uso [email protected]»(?<=watch\\?v=|/videos/|embed\\/|youtu.be\\/|\\/v\\/|\\/e\\/|watch\\?v%3D|watch\\?feature=player_embedded&v=|%2Fvideos%2F|embed%\u200C\u200B2F|youtu.be%2F|%2Fv%2F)[^#\\&\\?\\n]*»
    • me puedes dar un ejemplo, cuando esta expresión no está funcionando?
  3. 38

    Lo siento – no tengo suficiente rep para agregar un comentario a la respuesta que elijas.

    Después de pasar edades tratando de encontrar la sintaxis correcta para el regex, me he encontrado con este que me ha ayudado. Esperemos que podría ayudar a alguien más!

    NSString *regexString = @"(?<=v(=|/))([-a-zA-Z0-9_]+)|(?<=youtu.be/)([-a-zA-Z0-9_]+)";

    Tomado de aquí. Esto funciona para los siguientes formatos URL:

    • Esto funcionó para mí, sólo para mencionar que uou ned para el acceso a la en el rango de 0 a conseguirlo: NSRange videoIDRange = [partido rangeAtIndex:0]; NSString *videoID = [mensaje substringWithRange:videoIDRange];
    • Dis se da cooolest respuesta evaaa! Si fue combinado con dat Dima homie la respuesta
  4. 9

    Los tutoriales que son, probablemente, el hecho de ver son sólo las instrucciones sobre cómo utilizar expresiones regulares, que es también lo que usted desea utilizar en este caso.

    El Cacao en la clase que usted necesite usar es NSRegularExpression.

    Su real expresión de cadena dependerá del formato que usted está esperando la url desde la que se ve como youtube tiene varios. La función general será algo parecido a:

    + (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. 7

    Usted incluso no necesita expresiones regulares. Las siguientes obras, independientemente de la duración de la ID del vídeo y su posición dentro de la 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);
    • Mucho mejor que las expresiones regulares. Todavía no toma this en cuenta como youtube-dl no, pero bueno. 😉
    • Mi principio: si estamos en el desarrollo de buggy hacks, entonces al menos hay que ser elegante 😛 Gracias. (Por cierto: si entiendo tu punto de razón, mi error es fácilmente solucionable por separatimg la URL por los personajes en la ?# conjunto de caracteres…)
    • +1 : esto sólo trabajó conmigo…
  6. 3

    Basado en esta respuesta: PHP Regex para obtener vídeo de youtube ID?

    He adaptado un regex para c/objc/c++ cadena, la parte importante aquí es que la expresión regular no conseguir los vídeos de facebook u otros servicios.
    iOS regex se basa en: La UCI

    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;
    }

    Partidos:

    No coinciden:

  7. 2
    - (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. 2

    He utilizado la más votada respuesta a escribir un mejor, más restrictiva regex.

    NSString *regex = @"(?:youtube.com.+v[=/]|youtu.be/)([-a-zA-Z0-9_]+)";

    y, a continuación, usted puede obtener el ID de

    NSTextCheckingResult *match = [regex firstMatchInString:url
                                                    options:0
                                                      range:NSMakeRange(0, [url length])];
    NSRange videoIDRange = [match rangeAtIndex:1];
    NSString *youTubeID = [url substringWithRange:videoIDRange];
  9. 1

    Aquí está mi solución, la cual hace referencia de StackOveFlow. (Youtube I. D de análisis para los nuevos formatos de las direcciones URL)

    Hice algunas modificaciones.

    ///Este es el .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. 1

    Hay un montón de buenas respuestas aquí, pero pensé que podría ser beneficioso para algunos analizar múltiples id_video de una cadena. Esto podría ser una página web o un conjunto de diferentes URL.

    Ejemplo de contenido de la página

    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";

    Método

    -(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;
    }

    Salida

    ( 
    NLqAF9hrVbY,
    QLqAF9eeVbY,
    cAcqdjLCN7s
    )

    De crédito a @Alex por el Regex

    • Gracias por la detallada respuesta, pero no he sido capaz de averiguar qué es lo que YT_ID_EXTRACT_REGEX
    • No importa, lo imaginé. Para quienes se preguntan demasiado, sólo tiene que añadir #define YT_ID_EXTRACT_REGEX @"(?<=v(=|/))([-a-zA-Z0-9_]+)|(?<=youtu.be/)([-a-zA-Z0-9_]+)" a la parte superior de su archivo, en lugar de esta línea ‘NSString *extractRegex = @»(?<=v(=|/))([-a-zA-Z0-9_]+)|(?<=norton ghost.ser/)([-a-zA-Z0-9_]+)»‘
    • lo siento por el error en el código, he cambiado ahora, pero un poco demasiado tarde. Espero que el resto de la respuesta ayudado.
  11. 1

    La fusión de algunas de sus respuestas, yo diría que esta es la mejor respuesta:

    + (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. 1

    Swift 2 versión para @Alex respuesta

    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. 1

    Actualización 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])
    }

    Viejo respuesta:

    Un poco la manera más rápida de @Alex Swift 3 respuesta w/o el uso de NSString:

    Se puede forzar a probar el regex, porque sabemos que es válido.

    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])
    }

    O, si usted todavía desea 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. 0

    Aquí es el swift versión con @jt_ik del 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 ""
    }
    }
    • no funciona con el link que contiene el «vi».
  15. 0

    Swift 3 versión para @Alex respuesta

    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. -3

    Lo he descubierto por mí mismo…

    NSArray *videoURLSplit = [videoURL componentsSeparatedByString:@"v="];
    NSString *videoID = [[videoURLSplit objectAtIndex:1] substringToIndex:11];
    NSLog(@"%@",videoID);

    Muy simple… Todas las url de los vídeos contienen v=ID_VIDEO me acaba de separar la dirección url en una matriz y, a continuación, tomó la primera de 11 dígitos de lo que es después de v= como no podría ser más http OBTENER la información en la url…

    Gracias por la ayuda, aunque!

    • Tener cuidado con esto, ya que no es realmente cierto. Hay varios otros formatos de los videos puede venir como http://youtu.be/########### y youtube.com/v/###########.
    • Y lo que sucede cuando youtube comienza a utilizar los Identificadores de más de 11 caracteres. Usted necesitar considerar esta así.
    • Gracias por que, pero me carga youtube.com/watch?nomobile=1 esta dirección concreta en un webview y yo sólo permiten al usuario la búsqueda de vídeos y haga clic en ellos para apenas alrededor de cada vez que la url debe ser… youtube.com/v=VIDEO_ID
    • Echa un vistazo a este en TAN… stackoverflow.com/questions/6180138/…
    • a continuación, la solución debe estar bien. Tenga en cuenta que estas son exactamente el tipo de detalles que deben ser incluidos en la pregunta. De lo contrario, la gente no será capaz de ayudarle a llegar a la respuesta correcta.
    • Matemáticamente, no hay ninguna razón para utilizar más de 11 caracteres, pero lo que si se siente como el uso de 10 o 12 un día?
    • Yo no veo por qué eso habría de cambiar aleatoriamente a los 11 o 12 caracteres?

Dejar respuesta

Please enter your comment!
Please enter your name here