48 votes

Comment écrire des expressions régulières dans Objective C (NSRegularExpression)?

J'ai cette regex de travail quand je l'ai tester en PHP mais il ne fonctionne pas en Objective-C:

(?:www\.)?((?!-)[a-zA-Z0-9-]{2,63}(?<!-))\.?((?:[a-zA-Z0-9]{2,})?(?:\.[a-zA-Z0-9]{2,})?)

J'ai essayé d'échapper les caractères d'échappement mais ça n'aide pas non plus. Dois-je échapper à tout autre personnage?

C'est mon code en Objective-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);
}

-- UPDATE --

Cette expression renvoie (en PHP) le tableau avec les valeurs de "nom de domaine" et "tld.tld2" mais en Objective C-je obtenir une seule valeur: "nom-de-domaine.tld.tld2"

-- 2 --mise à JOUR

Cette regex extraits "nom de domaine" et " TLD " de la chaîne:

  • domain.com = (domaine, com)
  • domaine.co.uk = (domaine, co.royaume-uni)
  • -test-domain.co.u = (test-domain, co)
  • -test-domain.co.royaume-uni- = (test-domain, co.royaume-uni)
  • -test-domain.co.uk = (test-domain, co)
  • -test-domain.co-m = (test-domain)
  • -test-de-domaine -.co.uk = (test-domain)

il prend le nom de domaine valide (pas de départ ou de fin avec '-' et de 2 à 63 caractères de long), et jusqu'à deux parties d'un TLD si les pièces sont valides (au moins deux caractères ne contenant que des lettres et des chiffres)

Espérons que cette explication permet de.

78voto

Zaph Points 40557

Un NSTextCheckingResult a plusieurs éléments obtenus par l'indexation en elle.

[match rangeAtIndex:0]; est le plein match.
[match rangeAtIndex:1]; (si elle existe) est la première capture match du groupe.
etc.

Vous pouvez utiliser quelque chose comme ceci:

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

NSLog de sortie:

match: nom-de-domaine.tld.tld2
nom de domaine
tld.tld2

Ne tester que le match plages sont valides.

Plus simplement, dans ce cas:

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

14voto

hwaxxer Points 2336

Selon la documentation d' Apple , ces caractères doivent être cités (avec \) pour être traités comme des littéraux:

 * ? + [ ( ) { } ^ $ | \ . /
 

Cela vous aiderait également si vous pouviez expliquer ce que vous essayez d'atteindre. Avez-vous des appareils de test?

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X