代码之家  ›  专栏  ›  技术社区  ›  dreamlax

在nsstring中转义换行符和双引号等字符的最佳方法

  •  10
  • dreamlax  · 技术社区  · 15 年前

    假设我有一个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 回复  |  直到 15 年前
        1
  •  4
  •   danielpunkass    15 年前

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

    如果您希望转义的字符定义良好,我可能会坚持您提出的简单解决方案,粗略地替换字符的实例。

    请注意,如果源字符串中已经有转义字符,那么您可能希望避免对它们进行“双重转义”。实现这一点的一种方法是,在再次对字符串进行转义之前,对字符串中的任何转义字符串执行“unescape”操作。

    如果需要支持转义字符的变量集,请查看nsscanner方法“scanupcharactersfromset:intostring:”和“scancharactersfromset:intostring:”。您可以在nsscanner上使用这些方法浏览字符串,将“scanupto”部分中的部件复制到未更改的可变字符串中,并且仅在转义后才从特定字符集复制部件。

        2
  •  5
  •   Niklas Alvaeus    14 年前

    StringByAddingPercentEscapeSusingEncoding:nsutf8StringEncoding

        3
  •  4
  •   user296401    14 年前

    这将在nsstring中转义双引号:

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

    所以你要小心,也要避开逃跑的角色…

        4
  •  3
  •   Seth Kingsley    14 年前

    我认为在这样的情况下,一次对一个字符进行操作非常有用,可以是unichars或utf8字节。如果你用的是UTF-8,那么 vis(3) 将为您完成大部分工作(见下文)。我能问一下为什么要在双引号字符串中转义单引号吗?您打算如何处理多字节字符?在下面的示例中,我使用的是UTF-8,它使用C样式的八进制转义来编码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;
    }
    
        5
  •  2
  •   pheedsta    12 年前

    这是我过去使用过的一个非常有效的代码片段:

    - (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];   
    }
    
        6
  •  1
  •   fursund    14 年前

    这样做:

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

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

        7
  •  0
  •   Marc Charbonneau    15 年前

    您甚至可能希望研究使用regex库(有很多可用选项,regexkit是一个流行的选择)。找到一个预先编写的regex来转义处理特殊情况(如现有转义字符)的字符串并不难。