Regelmatige expressies in een Objective-C Cocoa-toepassing

Eerste Googlen geeft aan dat er geen ingebouwde manier is om reguliere expressies te doen in een Objective-C Cocoa-toepassing.

Dus vier vragen:

  1. Is dat echt waar?

  2. Maak je een grapje?

  3. Ok, is er dan een mooie open-source bibliotheek die je aanraadt?

  4. Wat zijn manieren om dichtbij genoeg te komen zonder een bibliotheek te importeren, misschien met de NSScanner-klasse?


Antwoord 1, autoriteit 100%

Ik heb gemerkt dat Apple vanaf iOS 4.0 een NSRegularExpression-klasse. Bovendien is de klasse vanaf 10.7 beschikbaar onder OS X.


Antwoord 2, autoriteit 30%

  1. Ja, er is geen regex-ondersteuning in Cocoa. Als je alleen geïnteresseerd bent in boolean matching, kun je NSPredicatedie ICU regex-syntaxis ondersteunt. Maar meestal ben je geïnteresseerd in de positie van de match of de positie van subexpressies, en kun je deze niet krijgen met NSPredicate.
  2. Zoals vermeld kunt u regex POSIX-functies. Maar ze worden als traag beschouwd en de regex-syntaxis is beperkt in vergelijking met andere oplossingen (ICU/pcre).
  3. Er zijn veel OSS-bibliotheken, CocoaDev heeft een uitgebreide lijst.
  4. RegExKitLitevereist bijvoorbeeld geen bibliotheken, voeg gewoon toe de .m en .h naar uw project.

    (Mijn klacht tegen RegExKitLite is dat het NSString via categorie uitbreidt, maar het kan ook als een functie worden beschouwd. Het gebruikt ook de niet-openbare ICU-bibliotheken die bij het besturingssysteem worden geleverd, wat niet wordt aanbevolen door Apple.)


Antwoord 3, autoriteit 13%

RegexKit is de beste die ik tot nu toe heb gevonden. Zeer Cacao: y. Ik gebruik de “Lite”-versie in verschillende van onze iPhone-apps:

sourceforge

lingonikorg


Antwoord 4, autoriteit 9%

U kunt de POSIX Regular Expressions-bibliotheek gebruiken (Yay voor een POSIX-compatibel besturingssysteem). Probeer

man 3 regex

Antwoord 5, autoriteit 6%

De goedkope en vuile hackoplossing die ik gebruik om REGEX- en JSON-parseerproblemen op te lossen, is door een UIWebView-object te maken en Javascript-functie(s) te injecteren om het parseren uit te voeren. De javascript-functie retourneert vervolgens een reeks van de waarde (of lijst met waarden) waar ik om geef. U kunt zelfs een kleine bibliotheekset met functies opslaan die zijn aangepast voor bepaalde taken en deze vervolgens naar behoefte oproepen.

Ik weet niet of deze techniek kan worden opgeschaald naar enorme hoeveelheden herhaalde parseerverzoeken, maar voor snelle transacties wordt de klus geklaard zonder afhankelijk te zijn van extra externe bronnen of code die u misschien niet begrijpt.


Antwoord 6, autoriteit 5%

Ik hou van het AGRegex-framework dat PCRE gebruikt, handig als je gewend bent aan de PCRE-syntaxis. De beste versie van dit framework is die in de Colloquy IRC-client, aangezien deze is geüpgraded om PCRE 6.7 te gebruiken:

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

Het is erg licht van gewicht, veel meer dan RegExKit (hoewel niet zo capabel natuurlijk).


Antwoord 7, autoriteit 4%

NSRegularExpressionis beschikbaar sinds Mac OS X v10.7 en IOS 4.0.


Antwoord 8, autoriteit 4%

Tijdens mijn zoektocht naar dit onderwerp kwam ik CocoaOnigurumategen die gebruikmaakt van Oniguruma, de reguliere expressie-engine achter Ruby1.9 en PHP5. Het lijkt een beetje nieuwer vergeleken met de bestaande OregKit(in het Japans) . Ik weet niet zeker hoe deze zich verhouden tot andere bindingen.


Antwoord 9, autoriteit 3%

Een beetje googelen, vond deze bibliotheek:
RegexOnNSString

Open source bibliotheek, met functies als:

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

en de klasse NSRegularExpressiongebruiken. Vrij eenvoudig te gebruiken en u hoeft zich nergens zorgen over te maken.

Houd er rekening mee dat NSRegularExpressionbeschikbaar is sinds Mac OS X v10.7 en IOS 4.0, zoals Datasmid al zei.


Antwoord 10

Ik maak het je gemakkelijk. Ik voeg een nieuw C++-bestand toe aan mijn Objective C-project, hernoem het als .mm en maak daarbinnen een standaard C++-klasse aan. Vervolgens maak ik een statische klassenmethode in de sectie “public:” voor een C++-functie die een NSString nodig heeft en een NSString retourneert (of NSArray, als dat is wat je wilt). Ik converteer vervolgens NSString naar C++ std::string als volgt:

// 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 <string>
std::string s = "";
if (([sInput != nil]) && (!([sInput isEqualTo:@""]))) {
  std::string sTemp([sInput UTF8String]);
  s = sTemp;
}

Vanaf daar kan ik regex_replace als volgt gebruiken:

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

Dan kan ik die std::string terug converteren naar een NSString met:

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

Als je deze C++ alleen voor deze functie gebruikt, dan vind je het misschien geschikt om dit bestand extra.mm (klassenaam Extra) aan te roepen en deze statische klassemethode in te voeren, en dan andere statische klassemethoden toe te voegen wanneer de situatie komt aan dat het gewoon logisch is om het in C++ te doen, omdat het in sommige gevallen minder gedoe is. (Er zijn gevallen waarin ObjC iets doet met minder regels code, en in sommige gevallen doet C++ het met minder regels code.)

P.S. Nog een andere manier is om een ​​.mm-bestand te gebruiken, maar een Objective C-wrapper te maken rond het gebruik van std::string en std::regex_replace() (of regex_match()).

Other episodes