Expressions régulières dans une application Objective-C Cocoa


173

La recherche initiale sur Google indique qu'il n'existe aucun moyen intégré de créer des expressions régulières dans une application Objective-C Cocoa.

Donc quatre questions:

  1. Est-ce vraiment vrai?

  2. Vous plaisantez j'espère?

  3. Ok, alors y a-t-il une belle bibliothèque open-source que vous recommandez?

  4. Quels sont les moyens de se rapprocher suffisamment sans importer de bibliothèque, peut-être avec la classe NSScanner?


4
Hmmmm ... Je me demande ce qui se passe si vous utilisez Monotouch. +1 pour la question.
Dan Rosenstark

Réponses:



42
  1. Oui, il n'y a pas de support regex dans Cocoa. Si vous n'êtes intéressé que par la correspondance booléenne, vous pouvez utiliser NSPredicate qui prend en charge la syntaxe d'expression régulière ICU. Mais généralement, vous êtes intéressé par la position de la correspondance ou la position des sous-expressions, et vous ne pouvez pas l'obtenir avec NSPredicate.
  2. Comme mentionné, vous pouvez utiliser les fonctions regex POSIX . Mais ils sont considérés comme lents, et la syntaxe des regex est limitée par rapport aux autres solutions (ICU / pcre ).
  3. Il existe de nombreuses bibliothèques OSS, CocoaDev en a une longue liste .
  4. RegExKitLite par exemple ne nécessite aucune bibliothèque, ajoutez simplement le .m et .h à votre projet.

    (Ma plainte contre RegExKitLite est qu'il étend NSString via la catégorie, mais il peut également être considéré comme une fonctionnalité. Il utilise également les bibliothèques ICU non publiques fournies avec le système d'exploitation, ce qui n'est pas recommandé par Apple.)


3
Gardez à l'esprit que les fonctions regex POSIX ne fonctionnent pas avec unicode (ASCII uniquement).
Tom Dalling

FYI que NSPredicate url est un lien cassé
taber

11
iOS prend en charge les expressions régulières pour les recherches de sous-chaînes, par exemple[myString rangeOfString:@"regex_here" options:NSRegularExpressionSearch]
Nestor

1
Également disponible dans Lion (10.7) #if MAC_OS_X_VERSION_10_7 <= MAC_OS_X_VERSION_MAX_ALLOWED || __IPHONE_3_2 <= __IPHONE_OS_VERSION_MAX_ALLOWED
Maciej Swic

Je trouve bien d'utiliser des bibliothèques ICU non publiques, car si vous avez besoin de les utiliser, c'est parce qu'il n'y a pas de support regex intégré dans votre version de Cocoa. Si vous utilisez ces bibliothèques, cela signifie également que vous construisez pour des systèmes plus anciens, qui ne seront plus modifiés car ils ne sont pas pris en charge. Si vous créez à la fois pour l'ancien et le nouveau, vous utilisez le RegExKitLite comme solution de secours si NSRegularExpression n'existe pas. (Oui, il y a encore des gens qui travaillent sur des systèmes plus anciens).

19

RegexKit est le meilleur que j'ai trouvé à ce jour. Très cacao: y. J'utilise la version "Lite" dans plusieurs de nos applications iPhone:

sourceforge

lingonikorg


1
Je seconde RegexKit Lite. Très agréable!
Dave Dribin

1
Cool, plus il y a de gens qui l'utilisent, mieux ça va probablement devenir!
avocade

12

Vous pouvez utiliser la bibliothèque d'expressions régulières POSIX (Yay pour un système d'exploitation compatible POSIX). Essayer

man 3 regex

Oh je vois. c'est une façon de le faire en C droit, qui devrait vraisemblablement fonctionner dans n'importe quelle application objective-C. cool merci! est-ce fondamentalement la manière acceptée de procéder?
dreeves

C'est un moyen qui ne nécessite aucune dépendance supplémentaire. Il y a d'autres choix, en termes de bibliothèques open source que vous pouvez importer (PCRE, pour les expressions régulières Perl, la bibliothèque Boost RegEx si vous utilisez Obj-C ++, ou d'autres listées dans d'autres réponses).
Adam Wright

Y a-t-il des inconvénients à mélanger directement C avec Objective-C? Pourriez-vous peut-être inclure un extrait de code pour la conversion vers et depuis NSString? Merci encore!
dreeves

Objective-C est construit sur C, donc vous ne mélangez vraiment rien. La plupart des gens utilisent cependant une bibliothèque, car elle offre une API plus facile à utiliser.
Marc Charbonneau

5
Et parce que les fonctions d'expression régulière POSIX ne fonctionnent qu'avec des chaînes ASCII.
Tom Dalling

8

La solution de piratage bon marché et sale que j'utilise pour résoudre les problèmes d'analyse REGEX et JSON consiste à créer un objet UIWebView et à injecter des fonctions Javascript pour effectuer l'analyse. La fonction javascript renvoie ensuite une chaîne de la valeur (ou liste de valeurs) qui me tient à cœur. En fait, vous pouvez stocker une petite bibliothèque de fonctions personnalisées pour des tâches particulières, puis les appeler selon vos besoins.

Je ne sais pas si cette technique s'adapte à d'énormes volumes de demandes d'analyse répétées, mais pour les transactions rapides, elle fait le travail sans dépendre de ressources externes supplémentaires ou de code que vous ne comprenez peut-être pas.


7

J'aime le framework AGRegex qui utilise PCRE, pratique si vous êtes habitué à la syntaxe PCRE. La meilleure version de ce framework est celle du client Colloquy IRC car il a été mis à niveau pour utiliser PCRE 6.7:

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

Il est très léger, bien plus que RegExKit (bien que pas aussi capable bien sûr).


Pourquoi moins capable s'il a une regex entièrement compatible avec Perl?
dreeves

Les méthodes d'assistance Objective-C associées ne sont pas aussi étendues que celles de RegExKit, mais elles conviennent à la plupart des cas.
Rob Keniger


5

Au cours de ma recherche sur ce sujet, je suis tombé sur CocoaOniguruma qui utilise Oniguruma , le moteur d'expression régulière derrière Ruby1.9 et PHP5. Il semble un peu plus récent par rapport à l' OregKit existant (en japonais). Je ne sais pas comment ceux-ci se comparent aux autres liaisons.


4

Googler un peu, j'ai trouvé cette bibliothèque: RegexOnNSString

Bibliothèque open source, contenant des fonctions telles que:

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

et en utilisant la NSRegularExpressionclasse. Très facile à utiliser et pas besoin de s'inquiéter de quoi que ce soit.

Veuillez noter que NSRegularExpressionc'est disponible depuis Mac OS X v10.7 et IOS 4.0, comme l'a mentionné Datasmid.


1

Je vous facilite la tâche. J'ajoute un nouveau fichier C ++ à mon projet Objective C, le renomme en .mm, puis crée une classe C ++ standard à l'intérieur. Ensuite, je crée une méthode de classe statique dans la section "public:" pour une fonction C ++ qui prend une NSString et renvoie une NSString (ou NSArray, si c'est ce que vous voulez). Je convertis ensuite NSString en C ++ std :: string comme ceci:

// 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;
}

À partir de là, je peux utiliser regex_replace comme ceci:

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

Ensuite, je peux reconvertir cette std :: string en une NSString avec:

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

Si vous n'utilisez ce C ++ que pour cette fonction, vous trouverez peut-être approprié d'appeler ce fichier extra.mm (nom de classe Extra) et de placer cette méthode de classe statique, puis d'ajouter d'autres méthodes de classe statique lorsque la situation se présente où il est logique de le faire en C ++ car c'est moins compliqué dans certains cas. (Il y a des cas où ObjC fait quelque chose avec moins de lignes de code, et certains cas où C ++ le fait avec moins de lignes de code.)

PS Encore une autre façon avec ceci est d'utiliser un fichier .mm mais de créer un wrapper Objective C autour de l'utilisation de std :: string et std :: regex_replace () (ou regex_match ()).

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.