Expresiones regulares en una aplicación Objective-C Cocoa

173

Google inicial indica que no hay una forma integrada de hacer expresiones regulares en una aplicación Objective-C Cocoa.

Entonces cuatro preguntas:

  1. ¿Es eso realmente cierto?

  2. ¿Me estás tomando el pelo?

  3. Ok, ¿hay una buena biblioteca de código abierto que recomiendas?

  4. ¿Cuáles son las formas de acercarse lo suficiente sin importar una biblioteca, tal vez con la clase NSScanner?

dreeves
fuente
44
Hmmmm ... Me pregunto qué pasará si usas Monotouch. +1 para la pregunta.
Dan Rosenstark

Respuestas:

141

Noté que a partir de iOS 4.0 Apple proporciona una clase NSRegularExpression . Además, a partir de 10,7, la clase está disponible en OS X .

Philip Jespersen
fuente
11
ahora también Mac OS X 10.7
user102008
42
  1. Sí, no hay soporte para expresiones regulares en Cocoa. Si solo le interesa la coincidencia booleana, puede usar NSPredicate, que admite la sintaxis de expresiones regulares de la UCI. Pero generalmente le interesa la posición de la coincidencia o la posición de las subexpresiones, y no puede obtenerla con NSPredicate.
  2. Como se mencionó, puede usar las funciones de expresiones regulares POSIX . Pero se consideran lentos y la sintaxis de expresiones regulares es limitada en comparación con otras soluciones (UCI / pcre ).
  3. Hay muchas bibliotecas OSS, CocoaDev tiene una extensa lista .
  4. RegExKitLite, por ejemplo, no requiere ninguna biblioteca, solo agregue .my .h a su proyecto.

    (Mi queja contra RegExKitLite es que extiende NSString a través de la categoría, pero también puede considerarse como una característica. También utiliza las bibliotecas de ICU no públicas que se envían con el sistema operativo, lo cual no es recomendado por Apple).

mfazekas
fuente
3
Tenga en cuenta que las funciones de expresiones regulares POSIX no funcionan con Unicode (solo ASCII).
Tom Dalling
FYI que NSPredicate url es un enlace roto
taber
11
iOS admite expresiones regulares para búsquedas de subcadenas, por ejemplo[myString rangeOfString:@"regex_here" options:NSRegularExpressionSearch]
Nestor
1
También disponible en 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
Me parece bien usar bibliotecas de UCI no públicas, porque si necesita usarlo, es porque no hay soporte de expresiones regulares incorporado en su versión de Cocoa. Si usa esas bibliotecas, también significa que está compilando para sistemas más antiguos, que ya no se cambiarán ya que no son compatibles. Si está compilando para viejos y nuevos, use RegExKitLite como reserva si NSRegularExpression no existe. (Sí, todavía hay personas trabajando en sistemas más antiguos).
19

RegexKit es el mejor que he encontrado hasta ahora. Muy cacao: y. Estoy usando la versión "Lite" en varias de nuestras aplicaciones para iPhone:

sourceforge

lingonikorg

avocade
fuente
1
Yo segundo RegexKit Lite. ¡Muy agradable!
Dave Dribin el
1
¡Genial, cuantas más personas lo usen, mejor será probablemente!
avocade
12

Puede usar la biblioteca de expresiones regulares POSIX (Yay para un sistema operativo compatible con POSIX). Tratar

man 3 regex
Adam Wright
fuente
Oh ya veo. Esta es una manera de hacerlo en C directo, que presumiblemente debería funcionar en cualquier aplicación de Objective-C. ¡Genial, gracias! ¿Esa es básicamente la forma aceptada de hacer esto?
Dreeves
Es una forma, que no requiere ninguna dependencia adicional. Hay otras opciones, en términos de bibliotecas de código abierto que podría importar (PCRE, para expresiones regulares de Perl, la biblioteca The Boost RegEx si está usando Obj-C ++ u otras que figuran en otras respuestas).
Adam Wright el
¿Alguna desventaja de mezclar directamente C con Objective-C? ¿Podría incluir un fragmento de código para convertir ay desde NSString? ¡gracias de nuevo!
Dreeves
Objective-C está construido sobre C, por lo que realmente no estás mezclando nada. Sin embargo, la mayoría de las personas usan una biblioteca, ya que ofrece una API que es más fácil de usar.
Marc Charbonneau
55
Y debido a que las funciones de expresiones regulares POSIX solo funcionan con cadenas ASCII.
Tom Dalling
8

La solución de pirateo barata y sucia que uso para resolver los problemas de análisis de REGEX y JSON es crear un objeto UIWebView e inyectar funciones de Javascript para realizar el análisis. La función de JavaScript luego devuelve una cadena del valor (o lista de valores) que me interesa. De hecho, puede almacenar un pequeño conjunto de funciones de biblioteca personalizadas para tareas particulares y luego simplemente llamarlas según sea necesario.

No sé si esta técnica escala a grandes volúmenes de solicitudes de análisis repetidas, pero para cosas transaccionales rápidas hace el trabajo sin depender de ningún recurso externo adicional o código que quizás no entiendas.

Mark Caufman
fuente
7

Me gusta el marco AGRegex que usa PCRE, útil si está acostumbrado a la sintaxis PCRE. La mejor versión de este marco es la del cliente Colloquy IRC, ya que se ha actualizado para usar PCRE 6.7:

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

Es muy liviano, mucho más que RegExKit (aunque, por supuesto, no es tan capaz).

Rob Keniger
fuente
¿Por qué menos capaz si tiene expresiones regulares compatibles con Perl?
Dreeves
Los métodos de ayuda Objective-C asociados no son tan extensos como los de RegExKit, sin embargo, están bien para la mayoría de los propósitos.
Rob Keniger
6

NSRegularExpression está disponible desde Mac OS X v10.7 e IOS 4.0.

bbaassssiiee
fuente
5

Durante mi búsqueda sobre este tema, me encontré con CocoaOniguruma que usa Oniguruma , el motor de Expresión Regular detrás de Ruby1.9 y PHP5. Parece un poco más nuevo en comparación con el OregonKit existente (en japonés). No estoy seguro de cómo se comparan con otros enlaces.

Newtonapple
fuente
4

Buscando un poco en Google, encontré esta biblioteca: RegexOnNSString

Biblioteca de código abierto, que contiene funciones como:

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

y usando NSRegularExpressionclase. Muy fácil de usar y sin necesidad de preocuparse por nada.

Tenga en cuenta que NSRegularExpressionestá disponible desde Mac OS X v10.7 e IOS 4.0, como mencionó Datasmid.

nickeyzzz
fuente
1

Yo te lo pongo fácil. Agrego un nuevo archivo C ++ a mi proyecto Objective C, lo renombro como .mm y luego creo una clase C ++ estándar dentro. Luego, hago un método de clase estática en la sección "public:" para una función C ++ que toma un NSString y devuelve un NSString (o NSArray, si eso es lo que quieres). Luego convierto NSString a C ++ std :: string así:

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

A partir de ahí, puedo usar regex_replace así:

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

Entonces, puedo convertir ese std :: string nuevamente en un NSString con:

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

Si solo está usando este C ++ solo para esta función, puede que le resulte adecuado llamar a este archivo extra.mm (nombre de clase Extra) y poner este método de clase estática, y luego agregar otros métodos de clase estática cuando llegue la situación donde tiene sentido hacerlo en C ++ porque es menos complicado en algunos casos. (Hay casos donde ObjC hace algo con menos líneas de código, y algunos casos donde C ++ lo hace con menos líneas de código).

PD Aún otra forma de hacerlo es usar un archivo .mm pero hacer un contenedor de Objective C alrededor del uso de std :: string y std :: regex_replace () (o regex_match ()).

Volomike
fuente