2012-02-14 13 views
44

Ho questo regex di lavoro quando prova in PHP, ma non funziona in Objective C:Come scrivere le espressioni regolari nell'obiettivo C (NSRegularExpression)?

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

ho cercato la fuga i caratteri di escape, ma questo non aiuta neanche. Dovrei sfuggire a qualsiasi altro personaggio?

Questo è il mio codice in 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); 
} 

- AGGIORNAMENTO -

Questa regex rendimenti (in PHP) l'array con i valori "domain-name" e "tld.tld2" ma in Objective C ottengo un solo valore: "dominio-name.tld.tld2"

- UPDATE 2 -

'nome di dominio' Questa regex estratti e 'TLD' dalla stringa:

  • domain.com = (dominio, com)
  • domain.co.uk = (dominio, co.uk)
  • -test-domain.co.u = (test-domain, co)
  • -test-domain.co.uk- = (test-domain, co.uk)
  • -test-domain.co.uk = (test-domain, co)
  • -Test-domain.co- m = (dominio-test)
  • -test-domain-.co.uk = (dominio-test)

prende il nome di dominio valido (non inizia o termina con '-' e tra 2 e 63 caratteri) e fino a due parti di un TLD se le parti sono valide (almeno due caratteri contenenti solo lettere e numeri)

Spero che questa spiegazione aiuti.

+0

convalida e-mail? – Hiren

+0

forse questo aiuta? http://stackoverflow.com/questions/5478170/regular-expression-in-ios – dom

+2

Penso che Dino stia chiedendo come convertire la regex esistente nel codice ObjectiveC. Non importa cosa fa la regex. –

risposta

70

A NSTextCheckingResult ha più elementi ottenuti indicizzandoli.

[match rangeAtIndex:0]; è la partita completa.
[match rangeAtIndex:1]; (se esiste) è la prima corrispondenza del gruppo di acquisizione.
ecc

Si può usare qualcosa di simile:

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

uscita NSLog:

partita: dominio-name.tld.tld2
domain-name
tld.tld2

Verificare che gli intervalli di corrispondenza siano validi.

Più semplicemente, in questo 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) 
} 

output di stampa:

partita: dominio-name.tld.tld2
matchText1: d OMain-name
matchText2: tld.tld2

Più semplicemente, in questo 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) 
} 

output di stampa:

matchText1: domain-name
matchText2: tld.tld2

+0

il mio codice sopra visualizza attualmente tutti i risultati corrispondenti (corrispondenza completa, nome dominio, TLD) e funziona quando eseguo il test di regex online ma restituisce solo il primo valore (corrispondenza completa) quando viene testato nell'obiettivo C. – budidino

+0

Ho un problema con la parte "NSMutableString stringWithString" perché la regex non corrisponde alle stesse cose online VS Obiettivo C – budidino

+1

Mi dispiace, avevi ragione. Sembra che non abbia capito come ottenere correttamente i risultati. Sono uno sviluppatore web nel mio core e Objective C, tutto ciò che cerco di fare almeno 2 volte più difficile di PHP :) Grazie ancora. – budidino

11

Secondo Apple's documentation, questi personaggi devono essere citato (usando \) per essere trattati come letterali:

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

Sarebbe anche utile se si potrebbe spiegare che cosa si sta cercando di ottenere. Hai qualche attrezzatura di prova?

+0

Nel senso regex standard? o essere trattati come operatori regex? –

+0

Ho provato regex in obj-c, ma non riesco a ottenere \ '' per funzionare. Qualche idea? – ZuluDeltaNiner

+10

È necessario prima uscire dalla barra rovesciata. \\\ [ –