在NSString中转义字符如newline和double-quote的最佳方法

时间:2009-02-23 22:33:52

标签: cocoa macos string

假设我有一个NSString(或NSMutableString),其中包含:

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

将其转化为最佳方式是什么:

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

我是否必须反复手动使用-replaceOccurrencesOfString:withString:来转义字符,还是有更简单的方法?这些字符串可能包含其他字母/语言的字符。

如何在其他语言中使用其他字符串类完成此操作?

7 个答案:

答案 0 :(得分:5)

stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding

答案 1 :(得分:4)

我认为没有任何内置方法可以“逃避”特定字符集。

如果您想要转义的字符定义明确,我可能会坚持使用您提出的简单解决方案,粗略地替换字符的实例。

请注意,如果您的源字符串中已经包含转义字符,那么您可能希望避免“双重转义”它们。实现这一目标的一种方法是通过“unes​​cape”字符串中的任何转义字符串,然后再将它们全部转义。

如果需要支持一组可变的转义字符,请查看NSScanner方法“scanUpToCharactersFromSet:intoString:”和“scanCharactersFromSet:intoString:”。你可以在NSScanner上使用这些方法来巡航字符串,将部分从“scanUpTo”部分复制到一个不变的可变字符串中,并在转义它们之后从特定字符集复制部分。

答案 2 :(得分:4)

这将在NSString中转义双引号:

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

所以你需要小心,也要逃避逃脱角色......

答案 3 :(得分:3)

我认为在这些情况下,一次操作一个字符非常有用,无论是UniChars还是UTF8字节。如果您使用的是UTF-8,那么vis(3)将为您完成大部分工作(见下文)。我可以问为什么你要在双引号字符串中转义单引号?你打算如何处理多字节字符?在下面的示例中,我使用的是UTF-8,使用C-Style八进制转义编码8位字符。这也可以通过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;
}

答案 4 :(得分:2)

这是我过去使用的一个代码段,效果很好:

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

答案 5 :(得分:1)

这样做:

NSString * encodedString = (NSString *)CFURLCreateStringByAddingPercentEscapes(
    NULL,
    (CFStringRef)unencodedString,
    NULL,
    (CFStringRef)@"!*'();:@&=+$,/?%#[]",
    kCFStringEncodingUTF8 );

参考:http://simonwoodside.com/weblog/2009/4/22/how_to_really_url_encode/

答案 6 :(得分:0)

您甚至可能希望使用正则表达式库(有很多选项,RegexKit是一个受欢迎的选择)。找到预先编写的正则表达式以逃避处理特殊情况(如现有转义字符)的字符串应该不会太难。