cocoa - una - heredoc php
La mejor forma de evitar caracteres como nueva lĂnea y comillas dobles en NSString (7)
Digamos que tengo un NSString (o NSMutableString) que contiene:
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?
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.
No creo que haya ningún método incorporado para "escapar" de un conjunto particular de caracteres.
Si los personajes de los que deseas escapar están bien definidos, probablemente me quedaré con la solución simple que propusiste, 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 "escapes dobles". 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.
Esto escapará de las comillas dobles en NSString:
NSString *escaped = [originalString stringByReplacingOccurrencesOfString:@"/"" withString:@"///""];
Entonces debes tener cuidado y también escapar del personaje de escape ...
stringByAddingPercentEscapesUsingEncoding: NSUTF8StringEncoding
Hacer esto:
NSString * encodedString = (NSString *)CFURLCreateStringByAddingPercentEscapes(
NULL,
(CFStringRef)unencodedString,
NULL,
(CFStringRef)@"!*''();:@&=+$,/?%#[]",
kCFStringEncodingUTF8 );
Referencia: http://simonwoodside.com/weblog/2009/4/22/how_to_really_url_encode/
Creo que en casos como estos, es útil operar un carácter a la vez, ya sea en UniChars o en UTF8 bytes. 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 planeas 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 puede deshacerse 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;
}
Este es un fragmento que he usado 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];
}