2009-02-23 18 views
10

Decir que tengo un NSString (o NSMutableString) que contiene:mejor manera de escapar de personajes como nueva línea y de comillas dobles en NSString

I said "Hello, world!". 
He said "My name's not World." 

¿Cuál es la mejor manera de convertir eso en:

I said \"Hello, world!\".\nHe said \"My name\'s not World.\" 

¿Tengo que usar manualmente -replaceOccurrencesOfString:withString: una y otra vez para escapar de los caracteres, o hay una manera más fácil? Estas cadenas pueden contener caracteres de otros alfabetos/idiomas.

¿Cómo se hace esto en otros idiomas con otras clases de cuerdas?

+0

Sin duda, no utilizar manualmente ese método una y otra vez.No sería difícil escribir un método que tome una serie de reemplazos a la vez. – Chuck

Respuesta

4

No creo que haya ningún método incorporado para "escapar" un determinado conjunto de caracteres.

Si los caracteres que desea escaparse están bien definidos, probablemente me quedaré con la solución simple que usted propuso, reemplazando las instancias de los personajes crudamente.

Tenga en cuenta que si su cadena de origen ya ha escapado de los caracteres, probablemente querrá evitar el "doble escape" de ellos. Una forma de lograr esto sería pasar y "desactivar" cualquier cadena de caracteres escapada en la cadena antes de volver a escapar de todos.

Si necesita admitir un conjunto variable de caracteres escapados, eche un vistazo a los métodos de NSScanner "scanUpToCharactersFromSet: intoString:" y "scanCharactersFromSet: intoString:". Puede usar estos métodos en NSScanner para recorrer una cadena, copiar las partes de la sección "scanUpTo" en una cadena mutable sin modificar, y copiar las partes de un juego de caracteres en particular solo después de escapar de ellas.

+0

Es mucho más complicado de lo que pensé que tendría que ser, pero hace bien el trabajo. – dreamlax

0

Es posible que desee examinar el uso de una biblioteca de expresiones regulares (hay muchas opciones disponibles, RegexKit es una opción popular). No debería ser demasiado difícil encontrar una expresión regular escrita previamente para escapar cadenas que maneja casos especiales como los caracteres escapados existentes.

4

Esto escapar comillas dobles en NSString:

NSString *escaped = [originalString stringByReplacingOccurrencesOfString:@"\"" withString:@"\\\""]; 

Así que hay que tener cuidado y también escapar el carácter de escape ...

5

stringByAddingPercentEscapesUsingEncoding: NSUTF8StringEncoding

3

Creo que en casos como estos, es útil para operar un carácter a la vez, ya sea en UniChars o en bytes UTF8. Si está utilizando UTF-8, entonces vis(3) hará la mayor parte del trabajo por usted (consulte a continuación). ¿Puedo preguntar por qué quiere escapar de una comilla simple dentro de una cadena de comillas dobles? ¿Cómo piensas manejar los caracteres de varios bytes? En el siguiente ejemplo, estoy usando UTF-8, codificando caracteres de 8 bits usando C-Style octal escapes. Esto también se puede deshacer por unvis(3).

#import <Foundation/Foundation.h> 
#import <vis.h> 

@interface NSString (Escaping) 

- (NSString *)stringByEscapingMetacharacters; 

@end 

@implementation NSString (Escaping) 

- (NSString *)stringByEscapingMetacharacters 
{ 
    const char *UTF8Input = [self UTF8String]; 
    char *UTF8Output = [[NSMutableData dataWithLength:strlen(UTF8Input) * 4 + 1 /* Worst case */] mutableBytes]; 
    char ch, *och = UTF8Output; 

    while ((ch = *UTF8Input++)) 
     if (ch == '\'' || ch == '\'' || ch == '\\' || ch == '"') 
     { 
      *och++ = '\\'; 
      *och++ = ch; 
     } 
     else if (isascii(ch)) 
      och = vis(och, ch, VIS_NL | VIS_TAB | VIS_CSTYLE, *UTF8Input); 
     else 
      och+= sprintf(och, "\\%03hho", ch); 

    return [NSString stringWithUTF8String:UTF8Output]; 
} 

@end 

int 
main(int argc, const char *argv[]) 
{ 
    NSAutoreleasePool *pool = [NSAutoreleasePool new]; 

    NSLog(@"%@", [@"I said \"Hello, world!\".\nHe said \"My name's not World.\"" stringByEscapingMetacharacters]); 

    [pool drain]; 
    return 0; 
} 
2

Este es un fragmento de código que he utilizado en el pasado que funciona bastante bien:

- (NSString *)escapeString:(NSString *)aString 
{ 
    NSMutableString *returnString = [[NSMutableString alloc] init]; 

    for(int i = 0; i < [aString length]; i++) { 

     unichar c = [aString characterAtIndex:i]; 

     // if char needs to be escaped 
     if((('\\' == c) || ('\'' == c)) || ('"' == c)) { 
      [returnString appendFormat:@"\\%c", c];    
     } else { 
      [returnString appendFormat:@"%c", c]; 
     } 
    } 

    return [returnString autorelease]; 
} 
Cuestiones relacionadas