¿Cómo escribir expresiones regulares en Objective C(NSRegularExpression)?
objective-c ios (2)
De acuerdo con la documentación de Apple , estos caracteres deben ser citados (usando /) para ser tratados como literales:
* ? + [ ( ) { } ^ $ | / . /
También ayudaría si pudiera explicar lo que está tratando de lograr. ¿Tienes algún accesorio de prueba?
Tengo esta expresión regular funcionando cuando la pruebo en PHP pero no funciona en el Objetivo C:
(?:www/.)?((?!-)[a-zA-Z0-9-]{2,63}(?<!-))/.?((?:[a-zA-Z0-9]{2,})?(?:/.[a-zA-Z0-9]{2,})?)
Intenté escapar de los personajes de escape, pero eso tampoco ayuda. ¿Debería escapar de cualquier otro personaje?
Este es mi código en el Objetivo C:
NSMutableString *searchedString = [NSMutableString stringWithString:@"domain-name.tld.tld2"];
NSError* error = nil;
NSRegularExpression* regex = [NSRegularExpression regularExpressionWithPattern:@"(?:www//.)?((?!-)[a-zA-Z0-9-]{2,63}(?<!-))//.?((?:[a-zA-Z0-9]{2,})?(?://.[a-zA-Z0-9]{2,})?)" options:0 error:&error];
NSArray* matches = [regex matchesInString:searchedString options:0 range:NSMakeRange(0, [searchedString length])];
for ( NSTextCheckingResult* match in matches )
{
NSString* matchText = [searchedString substringWithRange:[match range]];
NSLog(@"match: %@", matchText);
}
- ACTUALIZACIÓN -
Esta expresión regular devuelve (en PHP) la matriz con los valores "nombre de dominio" y "tld.tld2", pero en el Objetivo C solo obtengo un valor: "domain-name.tld.tld2"
- ACTUALIZACIÓN 2 -
Esta expresión regular extrae ''nombre de dominio'' y ''TLD'' de la cadena:
- domain.com = (domain, com)
- domain.co.uk = (dominio, co.uk)
- -test-domain.co.u = (test-dominio, co)
- -test-domain.co.uk- = (test-domain, co.uk)
- -test-domain.co.uk = (test-domain, co)
- -test-domain.co-m = (dominio de prueba)
- -test-domain-.co.uk = (dominio de prueba)
toma el nombre de dominio válido (no comienza ni termina con ''-'' y tiene una longitud de entre 2 y 63 caracteres), y hasta dos partes de un TLD si las partes son válidas (al menos dos caracteres contienen solo letras y números)
Espero que esta explicación ayude.
Un NSTextCheckingResult
tiene múltiples elementos obtenidos al NSTextCheckingResult
.
[match rangeAtIndex:0];
es el partido completo.
[match rangeAtIndex:1];
(si existe) es la primera coincidencia del grupo de captura.
etc.
Puedes usar algo como esto:
NSString *searchedString = @"domain-name.tld.tld2";
NSRange searchedRange = NSMakeRange(0, [searchedString length]);
NSString *pattern = @"(?:www//.)?((?!-)[a-zA-Z0-9-]{2,63}(?<!-))//.?((?:[a-zA-Z0-9]{2,})?(?://.[a-zA-Z0-9]{2,})?)";
NSError *error = nil;
NSRegularExpression* regex = [NSRegularExpression regularExpressionWithPattern: pattern options:0 error:&error];
NSArray* matches = [regex matchesInString:searchedString options:0 range: searchedRange];
for (NSTextCheckingResult* match in matches) {
NSString* matchText = [searchedString substringWithRange:[match range]];
NSLog(@"match: %@", matchText);
NSRange group1 = [match rangeAtIndex:1];
NSRange group2 = [match rangeAtIndex:2];
NSLog(@"group1: %@", [searchedString substringWithRange:group1]);
NSLog(@"group2: %@", [searchedString substringWithRange:group2]);
}
Salida de NSLog:
coinciden: nombreDeDominio.tld.tld2
nombre de dominio
tld.tld2
Haga una prueba de que los rangos de coincidencia son válidos.
Más simplemente en este caso:
NSString *searchedString = @"domain-name.tld.tld2";
NSRange searchedRange = NSMakeRange(0, [searchedString length]);
NSString *pattern = @"(?:www//.)?((?!-)[a-zA-Z0-9-]{2,63}(?<!-))//.?((?:[a-zA-Z0-9]{2,})?(?://.[a-zA-Z0-9]{2,})?)";
NSError *error = nil;
NSRegularExpression* regex = [NSRegularExpression regularExpressionWithPattern:pattern options:0 error:&error];
NSTextCheckingResult *match = [regex firstMatchInString:searchedString options:0 range: searchedRange];
NSLog(@"group1: %@", [searchedString substringWithRange:[match rangeAtIndex:1]]);
NSLog(@"group2: %@", [searchedString substringWithRange:[match rangeAtIndex:2]]);
Swift 3.0:
let searchedString = "domain-name.tld.tld2"
let nsSearchedString = searchedString as NSString
let searchedRange = NSMakeRange(0, searchedString.characters.count)
let pattern = "(?:www//.)?((?!-)[a-zA-Z0-9-]{2,63}(?<!-))//.?((?:[a-zA-Z0-9]{2,})?(?://.[a-zA-Z0-9]{2,})?)"
do {
let regex = try NSRegularExpression(pattern:pattern, options: [])
let matches = regex.matches(in:searchedString, options:[], range:searchedRange)
for match in matches {
let matchText = nsSearchedString.substring(with:match.range);
print("match: /(matchText)");
let group1 : NSRange = match.rangeAt(1)
let matchText1 = nsSearchedString.substring(with: group1)
print("matchText1: /(matchText1)")
let group2 = match.rangeAt(2)
let matchText2 = nsSearchedString.substring(with: group2)
print("matchText2: /(matchText2)")
}
} catch let error as NSError {
print(error.localizedDescription)
}
salida de impresión:
coinciden: nombreDeDominio.tld.tld2
matchText1: nombre de dominio
matchText2: tld.tld2
Más simplemente en este caso:
do {
let regex = try NSRegularExpression(pattern:pattern, options: [])
let match = regex.firstMatch(in:searchedString, options:[], range:searchedRange)
let matchText1 = nsSearchedString.substring(with: match!.rangeAt(1))
print("matchText1: /(matchText1)")
let matchText2 = nsSearchedString.substring(with: match!.rangeAt(2))
print("matchText2: /(matchText2)")
} catch let error as NSError {
print(error.localizedDescription)
}
salida de impresión:
matchText1: nombre de dominio
matchText2: tld.tld2