【问题标题】:Best way to escape characters like newline and double-quote in NSString在 NSString 中转义换行符和双引号等字符的最佳方法
【发布时间】:2012-05-18 14:04:10
【问题描述】:

假设我有一个 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: 来转义字符,还是有更简单的方法?这些字符串可能包含来自其他字母/语言的字符。

这是如何在其他语言中使用其他字符串类完成的?

【问题讨论】:

  • 我当然不会一遍又一遍地手动使用该方法。编写一个同时进行一系列替换的方法并不难。

标签: cocoa macos string


【解决方案1】:

stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding

【讨论】:

    【解决方案2】:

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

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

    请注意,如果您的源字符串中已经包含转义字符,那么您可能希望避免“双重转义”它们。实现这一点的一种方法是先遍历并“取消转义”字符串中的任何转义字符串,然后再将它们全部转义。

    如果您需要支持一组可变的转义字符,请查看 NSScanner 方法“scanUpToCharactersFromSet:intoString:”和“scanCharactersFromSet:intoString:”。您可以在 NSScanner 上使用这些方法来浏览字符串,将“scanUpTo”部分中的部分原样复制到可变字符串中,并仅在转义后从特定字符集中复制部分。

    【讨论】:

    • 它比我想象的要复杂得多,但它做得很好。
    【解决方案3】:

    这将转义 NSString 中的双引号:

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

    所以你需要小心并转义转义字符......

    【讨论】:

      【解决方案4】:

      我认为在这种情况下,一次操作一个字符是很有用的,无论是 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;
      }
      

      【讨论】:

        【解决方案5】:

        这是我过去用过的一个sn-p,效果很好:

        - (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】:

          这样做:

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

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

          【讨论】:

          • 那些是百分比转义,我想要反斜杠转义。
          【解决方案7】:

          您甚至可能想考虑使用正则表达式库(有很多可用选项,RegexKit 是一种流行的选择)。找到一个预先编写的正则表达式来转义处理特殊情况(如现有转义字符)的字符串应该不难。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2011-12-02
            • 1970-01-01
            • 1970-01-01
            • 2011-10-06
            • 1970-01-01
            相关资源
            最近更新 更多