2009-02-23 8 views
10

Sagen, ich habe ein NSString (oder NSMutableString) enthält:Beste Art und Weise Zeichen wie Newline und doppelte Anführungszeichen in NSString zu entkommen

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

Was ist der beste Weg, um dieses zu drehen:

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

Muss ich manuell -replaceOccurrencesOfString:withString: verwenden, um Zeichen zu entkommen, oder gibt es einen einfacheren Weg? Diese Zeichenfolgen können Zeichen aus anderen Alphabeten/Sprachen enthalten.

Wie wird dies in anderen Sprachen mit anderen String-Klassen gemacht?

+0

Ich würde sicherlich nicht manuell diese Methode immer und immer wieder verwenden.Es wäre nicht schwer, eine Methode zu schreiben, die eine Reihe von Ersetzungen auf einmal durchführt. – Chuck

Antwort

4

Ich glaube nicht, dass es eine eingebaute Methode gibt, um einen bestimmten Satz von Zeichen zu "entkommen".

Wenn die Charaktere, denen Sie entkommen möchten, gut definiert sind, würde ich wahrscheinlich bei der einfachen Lösung bleiben, die Sie vorgeschlagen haben, und die Instanzen der Charaktere grob ersetzen.

Seien Sie gewarnt, wenn Ihre Quellzeichenfolge bereits Zeichen enthält, die darin enthalten sind, dann werden Sie wahrscheinlich verhindern wollen, dass sie doppelt ausgeführt werden. Eine Möglichkeit, dies zu erreichen, wäre es, alle maskierten Zeichenketten in der Zeichenkette zu durchlaufen und zu "entsichern", bevor sie dann alle wieder entfernt werden.

Wenn Sie einen variablen Satz von Escapezeichen unterstützen müssen, sehen Sie sich die NSScanner-Methoden "scanUpToCharactersFromSet: intoString:" und "scanCharactersFromSet: intoString:" an. Sie können diese Methoden auf NSScanner verwenden, um durch eine Zeichenfolge zu navigieren, die Teile aus dem Abschnitt "scanUpTo" in eine änderbare Zeichenfolge zu kopieren und die Teile aus einem bestimmten Zeichensatz erst zu kopieren, nachdem Sie sie entfernt haben.

+0

Es ist viel komplizierter als ich dachte, dass es jemals sein müsste, aber es macht die Arbeit gut. – dreamlax

0

Vielleicht möchten Sie sogar mit einer Regex-Bibliothek arbeiten (es gibt viele Optionen, RegexKit ist eine beliebte Wahl). Es sollte nicht zu schwierig sein, eine vordefinierte Regex zu finden, um Strings zu entgehen, die spezielle Fälle wie existierende Escape-Zeichen behandeln.

4

Dies wird doppelte Anführungszeichen in NSString entkommen:

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

Sie müssen also vorsichtig sein und auch das Escape-Zeichen zu entkommen ...

5

stringByAddingPercentEscapesUsingEncoding: NSUTF8StringEncoding

3

Ich denke in Fällen wie diesen ist es nützlich, auf einem Zeichen zu arbeiten, entweder in UniChars oder UTF8 Bytes. Wenn Sie UTF-8 verwenden, erledigt vis(3) die meiste Arbeit für Sie (siehe unten). Kann ich fragen, warum Sie einem einfachen Anführungszeichen in einer Zeichenfolge mit doppelten Anführungszeichen entkommen möchten? Wie planen Sie die Verarbeitung von Multi-Byte-Zeichen? Im folgenden Beispiel verwende ich UTF-8, das 8-Bit-Zeichen mit C-Style-Oktal-Escapes kodiert. Dies kann auch durch unvis(3) rückgängig gemacht werden.

#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

Dies ist ein Ausschnitt ich in der Vergangenheit verwendet habe, die sehr gut funktioniert:

- (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]; 
} 
Verwandte Themen