2009-02-23 29 views
10

Nói rằng tôi có một NSString (hoặc NSMutableString) chứa:Cách tốt nhất để thoát khỏi nhân vật như xuống dòng và nhấn đúp quote trong NSString

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

cách tốt nhất để biến chúng thành là gì:

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

Tôi có phải sử dụng theo cách thủ công -replaceOccurrencesOfString:withString: lặp đi lặp lại để thoát khỏi các ký tự hoặc có cách nào dễ dàng hơn không? Các chuỗi này có thể chứa các ký tự từ các bảng chữ cái/ngôn ngữ khác.

Điều này được thực hiện bằng các ngôn ngữ khác với các lớp chuỗi khác như thế nào?

+0

Tôi chắc chắn sẽ không bằng tay sử dụng phương pháp đó hơn và hơn.Nó sẽ không khó để viết một phương pháp mà phải mất một loạt các thay thế tất cả cùng một lúc. – Chuck

Trả lời

4

Tôi không nghĩ có bất kỳ phương pháp tích hợp nào để "thoát" một tập hợp các ký tự cụ thể.

Nếu các ký tự bạn muốn thoát được xác định rõ, tôi có thể gắn bó với giải pháp đơn giản mà bạn đề xuất, thay thế các trường hợp của các ký tự một cách thô lỗ.

Được cảnh báo rằng nếu chuỗi nguồn của bạn đã có các ký tự thoát trong đó, thì có thể bạn sẽ muốn tránh "thoát kép" chúng. Một cách để đạt được điều này sẽ là đi qua và "unescape" bất kỳ chuỗi ký tự thoát trong chuỗi trước khi sau đó thoát tất cả chúng một lần nữa.

Nếu bạn cần hỗ trợ một tập hợp các ký tự thoát, hãy xem các phương pháp NSScanner "scanUpToCharactersFromSet: intoString:" và "scanCharactersFromSet: intoString:". Bạn có thể sử dụng các phương thức này trên NSScanner để duyệt qua một chuỗi, sao chép các phần từ phần "scanUpTo" vào một chuỗi có thể thay đổi không đổi và sao chép các phần từ một ký tự cụ thể chỉ sau khi thoát chúng.

+0

Nó phức tạp hơn rất nhiều so với những gì tôi nghĩ là nó sẽ có, nhưng nó thực hiện tốt công việc. – dreamlax

0

Bạn thậm chí có thể muốn xem xét sử dụng thư viện regex (có rất nhiều tùy chọn có sẵn, RegexKit là lựa chọn phổ biến). Nó không quá khó để tìm một regex viết sẵn để thoát khỏi các chuỗi xử lý các trường hợp đặc biệt như các ký tự thoát hiện có.

4

này sẽ thoát khỏi dấu ngoặc kép trong NSString:

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

Vì vậy, bạn cần phải cẩn thận và cũng có thể thoát khỏi nhân vật chạy thoát ...

5

stringByAddingPercentEscapesUsingEncoding: NSUTF8StringEncoding

3

Tôi nghĩ trong các trường hợp như vậy, sẽ hữu ích khi hoạt động trên một ký tự tại một thời điểm, hoặc bằng các chuỗi UniChars hoặc UTF8. Nếu bạn đang sử dụng UTF-8, thì vis(3) sẽ thực hiện hầu hết công việc cho bạn (xem bên dưới). Tôi có thể hỏi tại sao bạn muốn thoát khỏi một trích dẫn đơn trong một chuỗi được trích dẫn kép không? Bạn dự định xử lý các ký tự nhiều byte như thế nào? Trong ví dụ bên dưới, tôi đang sử dụng UTF-8, mã hóa các ký tự 8 bit bằng cách sử dụng dấu thoát vị bát phân kiểu C. Điều này cũng có thể được hoàn tác bởi 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

Đây là một đoạn tôi đã sử dụng trong quá khứ mà hoạt động khá tốt:

- (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]; 
} 
Các vấn đề liên quan