Espressioni regolari in un’applicazione Cocoa Objective-C

Googling iniziale indica che non esiste un modo integrato per eseguire espressioni regolari in un’applicazione Cocoa Objective-C.

Quindi quattro domande:

  1. È proprio vero?

  2. Ma stai scherzando?

  3. Ok, allora c’è una bella libreria open-source che consigli?

  4. Quali sono i modi per avvicinarsi abbastanza senza importare una libreria, magari con la class NSScanner?

Ho notato che da iOS 4.0 Apple fornisce una class NSRegularExpression . Inoltre, a partire da 10.7, la class è disponibile sotto OS X.

  1. Sì, non c’è supporto per l’espressione regolare in Cocoa. Se ti interessa solo la corrispondenza booleana, puoi usare NSPredicate che supporta la syntax regex dell’ICU. Ma di solito sei interessato alla posizione della partita o alla posizione delle sottoespressioni, e non puoi ottenerlo con NSPredicate.
  2. Come già detto, è ansible utilizzare le funzioni POSIX regex . Ma sono considerati lenti e la syntax regex è limitata rispetto ad altre soluzioni (ICU / pcre ).
  3. Ci sono molte librerie OSS, CocoaDev ha una lunga lista .
  4. RegExKitLite ad esempio non richiede alcuna libreria, basta aggiungere .m e .h al progetto.

    (Il mio reclamo contro RegExKitLite è che estende NSString via categoria, ma può anche essere considerato come una funzionalità. Utilizza anche le librerie ICU non pubbliche fornite con il sistema operativo, che non è raccomandato da Apple.)

RegexKit è il migliore che io abbia mai trovato. Molto cocoa: y. Sto usando la versione “Lite” in molte delle nostre app per iPhone:

sourceforge

lingonikorg

È ansible utilizzare la libreria POSIX Regular Expressions (Yay per un sistema operativo conforms a POSIX). Provare

 man 3 regex 

La soluzione di hacking economica e sporca che utilizzo per risolvere i problemi di analisi di REGEX e JSON consiste nel creare un object UIWebView e iniettare le funzioni JavaScript per eseguire l’analisi. La funzione javascript restituisce quindi una stringa del valore (o elenco di valori) a cui tengo. In effetti, è ansible memorizzare una piccola libreria di funzioni personalizzate per determinate attività e quindi chiamarle quando necessario.

Non so se questa tecnica ridimensiona a enormi volumi di richieste di analisi ripetute, ma per operazioni transazionali rapide svolge il lavoro senza dipendere da risorse esterne o codice che potresti non capire.

Mi piace il framework AGRegex che usa PCRE, utile se si è abituati alla syntax PCRE. La versione migliore di questo framework è quella del client IRC di Colloquy in quanto è stata aggiornata per utilizzare PCRE 6.7:

http://colloquy.info/project/browser/trunk/Frameworks/AGRegex

È molto leggero, molto più di RegExKit (anche se non altrettanto ovviamente).

NSRegularExpression è disponibile da Mac OS X v10.7 e IOS 4.0.

Durante la mia ricerca su questo argomento mi sono imbattuto in CocoaOniguruma che utilizza Oniguruma , il motore di Regular Expression dietro a Ruby1.9 e PHP5. Sembra un po ‘più recente rispetto all’originale OregKit (in giapponese). Non sono sicuro di come questi si accumulano contro altri attacchi.

Cercando su Google, ho trovato questa libreria: RegexOnNSString

Libreria open source, contenente funzioni come:

 -(NSString *) stringByReplacingRegexPattern:(NSString *)regex withString:(NSString *) replacement caseInsensitive:(BOOL)ignoreCase 

e usando la class NSRegularExpression . Abbastanza facile da usare e non c’è bisogno di preoccuparsi di nulla.

Si noti che NSRegularExpression è disponibile da Mac OS X v10.7 e IOS 4.0, come menzionato da Datasmid.

Lo faccio facile. Aggiungo un nuovo file C ++ al mio progetto Objective C, lo rinomiamo come .mm, e poi creo una class standard di C ++ all’interno. Quindi, creo un metodo di class statico nella sezione “public:” per una funzione C ++ che accetta un NSString e restituisce un NSString (o NSArray, se è ciò che si desidera). Quindi converto NSString in C ++ std :: string in questo modo:

 // If anyone knows a more efficient way, let me know in the comments. // The "if" condition below is because ObjC crashes if converting to // std::string if the string is nil or empty. // assume #include  std::string s = ""; if (([sInput != nil]) && (!([sInput isEqualTo:@""]))) { std::string sTemp([sInput UTF8String]); s = sTemp; } 

Da lì, posso usare regex_replace in questo modo:

 // assume #include  std::string sResult = std::regex_replace(sSource,sRegExp,sReplaceWith); 

Quindi, posso convertire quello std :: string in una NSString con:

 NSString *sResponse2 = @(sResult.c_str()); 

Se stai usando questo C ++ solo per questa funzione, allora potresti trovare adatto per chiamare questo file extra.mm (nome class Extra) e mettere questo metodo di class statica in, e quindi aggiungere altri metodi di class statici quando arriva la situazione dove ha senso farlo in C ++ perché in alcuni casi è meno fastidioso. (Ci sono casi in cui ObjC fa qualcosa con meno linee di codice, e in alcuni casi dove C ++ lo fa con meno linee di codice.)

PS Ancora un altro modo con questo è usare un file .mm ma creare un wrapper Objective C attorno all’uso di std :: string e std :: regex_replace () (o regex_match ()).