Expressões regulares em um aplicativo Objective-C Cocoa

O Googling inicial indica que não há uma maneira interna de fazer expressões regulares em um aplicativo Objective-C Cocoa.

Então, quatro perguntas:

  1. Isso é realmente verdade?

  2. Você está brincando comigo?

  3. Ok, então existe uma boa biblioteca de código aberto que você recomendaria?

  4. Quais são as maneiras de chegar perto o suficiente sem importar uma biblioteca, talvez com a class NSScanner?

Percebi que a partir do iOS 4.0, a Apple fornece uma class NSRegularExpression . Além disso, a partir de 10.7, a class está disponível no OS X.

  1. Sim, não há suporte para regex em Cocoa. Se você estiver interessado apenas em correspondência booleana, poderá usar o NSPredicate, que suporta a syntax de regex do ICU. Mas geralmente você está interessado na posição da correspondência ou na posição das subexpressões, e você não pode obtê-la com o NSPredicate.
  2. Como mencionado, você pode usar as funções regex POSIX . Mas eles são considerados lentos e a syntax da regex é limitada em comparação com outras soluções (ICU / pcre ).
  3. Existem muitas bibliotecas OSS, CocoaDev tem uma extensa lista .
  4. O RegExKitLite, por exemplo, não requer nenhuma biblioteca, apenas adicione o .m e o .h ao seu projeto.

    (Minha reclamação contra o RegExKitLite é que ele estende o NSString por categoria, mas também pode ser considerado como um recurso. Ele também usa as bibliotecas não públicas do ICU fornecidas com o SO, o que não é recomendado pela Apple.)

RegexKit é o melhor que eu já encontrei. Muito cacau: y. Estou usando a versão “Lite” em vários dos nossos aplicativos para iPhone:

sourceforge

lingonikorg

Você pode usar a biblioteca POSIX Regular Expressions (Yay para um sistema operacional compatível com POSIX). Experimentar

 man 3 regex 

A solução hack barata e suja que eu uso para resolver problemas de análise REGEX e JSON é criar um object UIWebView e injetar function (ões) Javascript para fazer a análise. A function javascript, em seguida, retorna uma string do valor (ou lista de valores) que me interessa. Na verdade, você pode armazenar um pequeno conjunto de bibliotecas de funções personalizadas para determinadas tarefas e, em seguida, apenas chamá-las conforme necessário.

Eu não sei se essa técnica é dimensionada para grandes volumes de solicitações de análise repetidas, mas para coisas transacionais rápidas, ela faz o trabalho sem depender de resources externos extras ou código que talvez você não entenda.

Eu gosto do framework AGRegex que usa PCRE, se você está acostumado com a syntax PCRE. A melhor versão deste framework é a do cliente de IRC Colloquy, já que ele foi atualizado para usar o PCRE 6.7:

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

É muito leve, muito mais do que RegExKit (embora não seja tão capaz, claro).

NSRegularExpression está disponível desde o Mac OS X v10.7 e o IOS 4.0.

Durante minha busca neste tópico me deparei com CocoaOniguruma que usa Oniguruma , o mecanismo de expressão regular por trás de Ruby1.9 e PHP5. Parece um pouco mais novo comparado ao OregKit existente (em japonês). Não tenho certeza de como isso se compara a outras ligações.

Pesquisando um pouco, encontrou esta biblioteca: RegexOnNSString

Biblioteca de código aberto, contendo funções como:

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

e usando a class NSRegularExpression . Bastante fácil de usar e não precisa se preocupar com nada.

Observe que o NSRegularExpression está disponível desde o Mac OS X v10.7 e o IOS 4.0, conforme mencionado no Datasmid.

Eu facilito. Eu adiciono um novo arquivo C ++ ao meu projeto Objective C, renomeio como .mm e, em seguida, criar uma class C ++ padrão dentro. Então, eu faço um método de class estático na seção “public:” para uma function C ++ que leva um NSString e retorna um NSString (ou NSArray, se é isso que você quer). Eu então converter NSString para C ++ std :: string da seguinte forma:

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

De lá, eu posso usar o regex_replace assim:

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

Então, eu posso converter esse std :: string de volta em um NSString com:

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

Se você está usando apenas este C ++ apenas para esta function, então você pode achar adequado chamar este arquivo extra.mm (nome da class Extra) e colocar este método de class estático, e então adicionar outros methods de class estática quando a situação chegar onde faz sentido fazê-lo em C ++ porque é menos trabalhoso em alguns casos. (Há casos em que o ObjC faz algo com menos linhas de código e alguns casos em que o C ++ o faz com menos linhas de código.)

PS Ainda assim, uma outra maneira é usar um arquivo .mm, mas fazer um wrapper do Objective C em torno do uso de std :: string e std :: regex_replace () (ou regex_match ()).