【问题标题】:HTML character decoding in Objective-C / Cocoa TouchObjective-C / Cocoa Touch 中的 HTML 字符解码
【发布时间】:2019-09-24 18:02:55
【问题描述】:

首先,我发现了这个:Objective C HTML escape/unescape,但它对我不起作用。

我的编码字符(来自 RSS 提要,顺便说一句)如下所示:&

我在网上搜索并找到了相关的讨论,但没有解决我的特定编码,我认为它们被称为十六进制字符。

【问题讨论】:

  • 此评论是在原始问题发布六个月后发布的,因此更适合那些偶然发现此问题并寻找答案和解决方案的人。最近出现了一个非常相似的问题,我回答了 stackoverflow.com/questions/2254862/… 它使用 RegexKitLite 和 Blocks 来搜索和替换字符串中的 &#...; 及其等效字符。
  • 具体是什么“不起作用”?我在这个问题中没有看到任何与之前的问题不重复的内容。
  • 十进制。十六进制为8
  • 十进制和十六进制的区别在于十进制是以 10 为底,而十六进制是以 16 为底。 “38”是每个碱基中不同的数字;在 10 进制中,它是 3×10 + 8×1 = 三十八,而在 16 进制中,它是 3×16 + 8×1 = 五十六。更高的数字是基数的(倍数)更高的幂;最低的整数是base0(= 1),下一个更高的数字是base1(= base),下一个是base**2(= base * base)等等。这是工作中的指数。

标签: iphone html objective-c cocoa cocoa-touch


【解决方案1】:

查看我的NSString category for HTML。以下是可用的方法:

- (NSString *)stringByConvertingHTMLToPlainText;
- (NSString *)stringByDecodingHTMLEntities;
- (NSString *)stringByEncodingHTMLEntities;
- (NSString *)stringWithNewLinesAsBRs;
- (NSString *)stringByRemovingNewLinesAndWhitespace;

【讨论】:

  • 老兄,功能很棒。你的 stringByDecodingXMLEntities 方法让我很开心!谢谢!
  • 没问题 ;) 很高兴你发现它有用!
  • 经过几个小时的搜索,我知道这是唯一真正有效的方法。 NSString 对于可以做到这一点的字符串方法来说已经过期了。干得好。
  • 我发现 Michael 的许可证上的 (2) 对我的用例来说过于严格,所以我使用了 Nikita 的解决方案。包括来自 google 工具箱的三个 Apache-2.0 许可文件对我来说非常有用。
  • ARC 的代码更新会很方便.. Xcode 在构建时会抛出大量 ARC 错误和警告
【解决方案2】:

丹尼尔的那个基本上很好,我在那里修复了一些问题:

  1. 删除了 NSSCanner 的跳过字符(否则两个连续实体之间的空格将被忽略

    [扫描仪 setCharactersToBeSkipped:nil];

  2. 修复了当存在孤立的“&”符号时的解析(我不确定这个的“正确”输出是什么,我只是将它与 firefox 进行了比较):

例如

    &#ABC DF & B'  & C' Items (288)

这里是修改后的代码:

- (NSString *)stringByDecodingXMLEntities {
    NSUInteger myLength = [self length];
    NSUInteger ampIndex = [self rangeOfString:@"&" options:NSLiteralSearch].location;

    // Short-circuit if there are no ampersands.
    if (ampIndex == NSNotFound) {
        return self;
    }
    // Make result string with some extra capacity.
    NSMutableString *result = [NSMutableString stringWithCapacity:(myLength * 1.25)];

    // First iteration doesn't need to scan to & since we did that already, but for code simplicity's sake we'll do it again with the scanner.
    NSScanner *scanner = [NSScanner scannerWithString:self];

    [scanner setCharactersToBeSkipped:nil];

    NSCharacterSet *boundaryCharacterSet = [NSCharacterSet characterSetWithCharactersInString:@" \t\n\r;"];

    do {
        // Scan up to the next entity or the end of the string.
        NSString *nonEntityString;
        if ([scanner scanUpToString:@"&" intoString:&nonEntityString]) {
            [result appendString:nonEntityString];
        }
        if ([scanner isAtEnd]) {
            goto finish;
        }
        // Scan either a HTML or numeric character entity reference.
        if ([scanner scanString:@"&" intoString:NULL])
            [result appendString:@"&"];
        else if ([scanner scanString:@"'" intoString:NULL])
            [result appendString:@"'"];
        else if ([scanner scanString:@""" intoString:NULL])
            [result appendString:@"\""];
        else if ([scanner scanString:@"<" intoString:NULL])
            [result appendString:@"<"];
        else if ([scanner scanString:@"&gt;" intoString:NULL])
            [result appendString:@">"];
        else if ([scanner scanString:@"&#" intoString:NULL]) {
            BOOL gotNumber;
            unsigned charCode;
            NSString *xForHex = @"";

            // Is it hex or decimal?
            if ([scanner scanString:@"x" intoString:&xForHex]) {
                gotNumber = [scanner scanHexInt:&charCode];
            }
            else {
                gotNumber = [scanner scanInt:(int*)&charCode];
            }

            if (gotNumber) {
                [result appendFormat:@"%C", (unichar)charCode];

                [scanner scanString:@";" intoString:NULL];
            }
            else {
                NSString *unknownEntity = @"";

                [scanner scanUpToCharactersFromSet:boundaryCharacterSet intoString:&unknownEntity];


                [result appendFormat:@"&#%@%@", xForHex, unknownEntity];

                //[scanner scanUpToString:@";" intoString:&unknownEntity];
                //[result appendFormat:@"&#%@%@;", xForHex, unknownEntity];
                NSLog(@"Expected numeric character entity but got &#%@%@;", xForHex, unknownEntity);

            }

        }
        else {
            NSString *amp;

            [scanner scanString:@"&" intoString:&amp];  //an isolated & symbol
            [result appendString:amp];

            /*
            NSString *unknownEntity = @"";
            [scanner scanUpToString:@";" intoString:&unknownEntity];
            NSString *semicolon = @"";
            [scanner scanString:@";" intoString:&semicolon];
            [result appendFormat:@"%@%@", unknownEntity, semicolon];
            NSLog(@"Unsupported XML character entity %@%@", unknownEntity, semicolon);
             */
        }

    }
    while (![scanner isAtEnd]);

finish:
    return result;
}

【讨论】:

  • 这应该是问题的明确答案!!谢谢!
  • 这很好用。不幸的是,由于 ARC 问题,评分最高的答案的代码不再起作用,但确实如此。
  • @TedKulp 它工作得很好,你只需要为每个文件禁用 ARC。 stackoverflow.com/questions/6646052/…
  • 如果可以的话,我会为你竖起大拇指。
  • 为 2016+ 年仍在访问此问题的人提供 Swift 翻译:stackoverflow.com/a/35303635/1153630
【解决方案3】:

从 iOS 7 开始,您可以使用带有 NSHTMLTextDocumentType 属性的 NSAttributedString 本地解码 HTML 字符:

NSString *htmlString = @"&#63743; &amp; &#38; &lt; &gt; &trade; &copy; &hearts; &clubs; &spades; &diams;";
NSData *stringData = [htmlString dataUsingEncoding:NSUTF8StringEncoding];

NSDictionary *options = @{NSDocumentTypeDocumentAttribute:NSHTMLTextDocumentType};
NSAttributedString *decodedString;
decodedString = [[NSAttributedString alloc] initWithData:stringData
                                                 options:options
                                      documentAttributes:NULL
                                                   error:NULL];

解码后的属性字符串现在将显示为: & & ™ © ♥ ♣ ♠ ♦。

注意:这只有在主线程上调用时才有效。

【讨论】:

  • 如果您不需要支持 iOS 6 及更早版本的最佳答案
  • 不,如果有人想在 bg 线程上对其进行编码,这不是最好的;O
  • 这适用于解码实体,但它也弄乱了非编码的破折号。
  • 这是强制发生在主线程上的。因此,如果您不必这样做,您可能不想这样做。
  • 它只是在涉及 UITableView 时挂起 GUI。因此,无法正常工作。
【解决方案4】:

那些被称为Character Entity References。当它们采用&amp;#&lt;number&gt;; 的形式时,它们被称为数字实体引用。基本上,它是应该被替换的字节的字符串表示形式。以&amp;#038;为例,表示ISO-8859-1字符编码方案中值为38的字符,即&amp;

&符号必须在 RSS 中编码的原因是它是一个保留的特殊字符。

您需要做的是解析字符串并将实体替换为与&amp;#; 之间的值匹配的字节。我不知道在目标 C 中有什么好方法可以做到这一点,但 this stack overflow question 可能会有所帮助。

编辑:自从两年前回答这个问题以来,有一些很好的解决方案;请参阅下面的@Michael Waterfall 的答案。

【讨论】:

  • +1 我正要提交完全相同的答案(包括相同的链接,不少!)
  • “基本上,它是应该被替换的字节的字符串表示形式。”更像性格。这是文本,不是数据;将文本转换为数据时,字符可能会占用多个字节,具体取决于字符和编码。
  • 感谢您的回复。你说“它代表ISO-8859-1字符编码方案中值为38的字符,即&”。您确定吗?你有这种类型的字符表的链接吗?因为据我记得那是一个单引号。
  • en.wikipedia.org/wiki/ISO/IEC_8859-1#ISO-8859-1 或者直接输入 &进入谷歌。
  • 那么 &或 ©符号?
【解决方案5】:

似乎没有人提到最简单的选项之一:Google Toolbox for Mac
(尽管名称如此,但它也适用于 iOS。)

https://github.com/google/google-toolbox-for-mac/blob/master/Foundation/GTMNSString%2BHTML.h

/// Get a string where internal characters that are escaped for HTML are unescaped 
//
///  For example, '&amp;' becomes '&'
///  Handles &#32; and &#x32; cases as well
///
//  Returns:
//    Autoreleased NSString
//
- (NSString *)gtm_stringByUnescapingFromHTML;

而且我只需要在项目中包含三个文件:header、implementation 和 GTMDefines.h

【讨论】:

  • 这三个脚本我已经包含了,但是现在怎么使用呢?
  • @borut-t [myString gtm_stringByUnescapingFromHTML]
  • 我选择只包含这三个文件,所以我需要这样做以使其与 arc 兼容:code.google.com/p/google-toolbox-for-mac/wiki/ARC_Compatibility
  • 我不得不说这是迄今为止最简单、最轻量级的解决方案
  • 我希望我可以让它完全工作。它似乎跳过了我的字符串中的许多。
【解决方案6】:

我应该在 GitHub 或其他地方发布这个。这属于 NSString 类别,使用 NSScanner 进行实现,并处理十六进制和十进制数字字符实体以及通常的符号实体。

此外,它相对优雅地处理格式错误的字符串(当您有一个 & 后跟无效的字符序列时),这在我使用此代码的 released app 中证明是至关重要的。

- (NSString *)stringByDecodingXMLEntities {
    NSUInteger myLength = [self length];
    NSUInteger ampIndex = [self rangeOfString:@"&" options:NSLiteralSearch].location;

    // Short-circuit if there are no ampersands.
    if (ampIndex == NSNotFound) {
        return self;
    }
    // Make result string with some extra capacity.
    NSMutableString *result = [NSMutableString stringWithCapacity:(myLength * 1.25)];

    // First iteration doesn't need to scan to & since we did that already, but for code simplicity's sake we'll do it again with the scanner.
    NSScanner *scanner = [NSScanner scannerWithString:self];
    do {
        // Scan up to the next entity or the end of the string.
        NSString *nonEntityString;
        if ([scanner scanUpToString:@"&" intoString:&nonEntityString]) {
            [result appendString:nonEntityString];
        }
        if ([scanner isAtEnd]) {
            goto finish;
        }
        // Scan either a HTML or numeric character entity reference.
        if ([scanner scanString:@"&amp;" intoString:NULL])
            [result appendString:@"&"];
        else if ([scanner scanString:@"&apos;" intoString:NULL])
            [result appendString:@"'"];
        else if ([scanner scanString:@"&quot;" intoString:NULL])
            [result appendString:@"\""];
        else if ([scanner scanString:@"&lt;" intoString:NULL])
            [result appendString:@"<"];
        else if ([scanner scanString:@"&gt;" intoString:NULL])
            [result appendString:@">"];
        else if ([scanner scanString:@"&#" intoString:NULL]) {
            BOOL gotNumber;
            unsigned charCode;
            NSString *xForHex = @"";

            // Is it hex or decimal?
            if ([scanner scanString:@"x" intoString:&xForHex]) {
                gotNumber = [scanner scanHexInt:&charCode];
            }
            else {
                gotNumber = [scanner scanInt:(int*)&charCode];
            }
            if (gotNumber) {
                [result appendFormat:@"%C", charCode];
            }
            else {
                NSString *unknownEntity = @"";
                [scanner scanUpToString:@";" intoString:&unknownEntity];
                [result appendFormat:@"&#%@%@;", xForHex, unknownEntity];
                NSLog(@"Expected numeric character entity but got &#%@%@;", xForHex, unknownEntity);
            }
            [scanner scanString:@";" intoString:NULL];
        }
        else {
            NSString *unknownEntity = @"";
            [scanner scanUpToString:@";" intoString:&unknownEntity];
            NSString *semicolon = @"";
            [scanner scanString:@";" intoString:&semicolon];
            [result appendFormat:@"%@%@", unknownEntity, semicolon];
            NSLog(@"Unsupported XML character entity %@%@", unknownEntity, semicolon);
        }
    }
    while (![scanner isAtEnd]);

finish:
    return result;
}

【讨论】:

  • 一段非常有用的代码,但是它确实有几个 Walty 解决的问题。感谢分享!
  • 你知道一种通过解码 XML 实体(如 µ)来显示 lambda、mu、nu、pi 符号的方法吗? ...等等 ????
  • 你应该避免使用gotos 作为它糟糕的代码风格。您应该将goto finish; 行替换为break;
【解决方案7】:

这是我使用RegexKitLite 框架的方式:

-(NSString*) decodeHtmlUnicodeCharacters: (NSString*) html {
NSString* result = [html copy];
NSArray* matches = [result arrayOfCaptureComponentsMatchedByRegex: @"\\&#([\\d]+);"];

if (![matches count]) 
    return result;

for (int i=0; i<[matches count]; i++) {
    NSArray* array = [matches objectAtIndex: i];
    NSString* charCode = [array objectAtIndex: 1];
    int code = [charCode intValue];
    NSString* character = [NSString stringWithFormat:@"%C", code];
    result = [result stringByReplacingOccurrencesOfString: [array objectAtIndex: 0]
                                               withString: character];      
}   
return result;  

}

希望这会对某人有所帮助。

【讨论】:

    【解决方案8】:

    你可以只使用这个函数来解决这个问题。

    + (NSString*) decodeHtmlUnicodeCharactersToString:(NSString*)str
    {
        NSMutableString* string = [[NSMutableString alloc] initWithString:str];  // #&39; replace with '
        NSString* unicodeStr = nil;
        NSString* replaceStr = nil;
        int counter = -1;
    
        for(int i = 0; i < [string length]; ++i)
        {
            unichar char1 = [string characterAtIndex:i];    
            for (int k = i + 1; k < [string length] - 1; ++k)
            {
                unichar char2 = [string characterAtIndex:k];    
    
                if (char1 == '&'  && char2 == '#' ) 
                {   
                    ++counter;
                    unicodeStr = [string substringWithRange:NSMakeRange(i + 2 , 2)];    
                    // read integer value i.e, 39
                    replaceStr = [string substringWithRange:NSMakeRange (i, 5)];     //     #&39;
                    [string replaceCharactersInRange: [string rangeOfString:replaceStr] withString:[NSString stringWithFormat:@"%c",[unicodeStr intValue]]];
                    break;
                }
            }
        }
        [string autorelease];
    
        if (counter > 1)
            return  [self decodeHtmlUnicodeCharactersToString:string]; 
        else
            return string;
    }
    

    【讨论】:

      【解决方案9】:

      这是Walty Yeung's answer 的 Swift 版本:

      extension String {
          static private let mappings = ["&quot;" : "\"","&amp;" : "&", "&lt;" : "<", "&gt;" : ">","&nbsp;" : " ","&iexcl;" : "¡","&cent;" : "¢","&pound;" : " £","&curren;" : "¤","&yen;" : "¥","&brvbar;" : "¦","&sect;" : "§","&uml;" : "¨","&copy;" : "©","&ordf;" : " ª","&laquo" : "«","&not" : "¬","&reg" : "®","&macr" : "¯","&deg" : "°","&plusmn" : "±","&sup2; " : "²","&sup3" : "³","&acute" : "´","&micro" : "µ","&para" : "¶","&middot" : "·","&cedil" : "¸","&sup1" : "¹","&ordm" : "º","&raquo" : "»&","frac14" : "¼","&frac12" : "½","&frac34" : "¾","&iquest" : "¿","&times" : "×","&divide" : "÷","&ETH" : "Ð","&eth" : "ð","&THORN" : "Þ","&thorn" : "þ","&AElig" : "Æ","&aelig" : "æ","&OElig" : "Œ","&oelig" : "œ","&Aring" : "Å","&Oslash" : "Ø","&Ccedil" : "Ç","&ccedil" : "ç","&szlig" : "ß","&Ntilde;" : "Ñ","&ntilde;":"ñ",]
      
          func stringByDecodingXMLEntities() -> String {
      
              guard let _ = self.rangeOfString("&", options: [.LiteralSearch]) else {
                  return self
              }
      
              var result = ""
      
              let scanner = NSScanner(string: self)
              scanner.charactersToBeSkipped = nil
      
              let boundaryCharacterSet = NSCharacterSet(charactersInString: " \t\n\r;")
      
              repeat {
                  var nonEntityString: NSString? = nil
      
                  if scanner.scanUpToString("&", intoString: &nonEntityString) {
                      if let s = nonEntityString as? String {
                          result.appendContentsOf(s)
                      }
                  }
      
                  if scanner.atEnd {
                      break
                  }
      
                  var didBreak = false
                  for (k,v) in String.mappings {
                      if scanner.scanString(k, intoString: nil) {
                          result.appendContentsOf(v)
                          didBreak = true
                          break
                      }
                  }
      
                  if !didBreak {
      
                      if scanner.scanString("&#", intoString: nil) {
      
                          var gotNumber = false
                          var charCodeUInt: UInt32 = 0
                          var charCodeInt: Int32 = -1
                          var xForHex: NSString? = nil
      
                          if scanner.scanString("x", intoString: &xForHex) {
                              gotNumber = scanner.scanHexInt(&charCodeUInt)
                          }
                          else {
                              gotNumber = scanner.scanInt(&charCodeInt)
                          }
      
                          if gotNumber {
                              let newChar = String(format: "%C", (charCodeInt > -1) ? charCodeInt : charCodeUInt)
                              result.appendContentsOf(newChar)
                              scanner.scanString(";", intoString: nil)
                          }
                          else {
                              var unknownEntity: NSString? = nil
                              scanner.scanUpToCharactersFromSet(boundaryCharacterSet, intoString: &unknownEntity)
                              let h = xForHex ?? ""
                              let u = unknownEntity ?? ""
                              result.appendContentsOf("&#\(h)\(u)")
                          }
                      }
                      else {
                          scanner.scanString("&", intoString: nil)
                          result.appendContentsOf("&")
                      }
                  }
      
              } while (!scanner.atEnd)
      
              return result
          }
      }
      

      【讨论】:

        【解决方案10】:

        实际上 Michael Waterfall 的伟大 MWFeedParser 框架(参考他的回答)已经被 rmchaara 分叉了,他已经更新了 ARC 支持!

        你可以在 Github here找到它

        它真的很好用,我使用了 stringByDecodingHTMLEntities 方法并且完美无缺。

        【讨论】:

        • 这修复了 ARC 问题 - 但引入了一些警告。我认为忽略它们是安全的?
        【解决方案11】:

        好像您需要另一种解决方案!这个很简单也很有效:

        @interface NSString (NSStringCategory)
        - (NSString *) stringByReplacingISO8859Codes;
        @end
        
        
        @implementation NSString (NSStringCategory)
        - (NSString *) stringByReplacingISO8859Codes
        {
            NSString *dataString = self;
            do {
                //*** See if string contains &# prefix
                NSRange range = [dataString rangeOfString: @"&#" options: NSRegularExpressionSearch];
                if (range.location == NSNotFound) {
                    break;
                }
                //*** Get the next three charaters after the prefix
                NSString *isoHex = [dataString substringWithRange: NSMakeRange(range.location + 2, 3)];
                //*** Create the full code for replacement
                NSString *isoString = [NSString stringWithFormat: @"&#%@;", isoHex];
                //*** Convert to decimal integer
                unsigned decimal = 0;
                NSScanner *scanner = [NSScanner scannerWithString: [NSString stringWithFormat: @"0%@", isoHex]];
                [scanner scanHexInt: &decimal];
                //*** Use decimal code to get unicode character
                NSString *unicode = [NSString stringWithFormat:@"%C", decimal];
                //*** Replace all occurences of this code in the string
                dataString = [dataString stringByReplacingOccurrencesOfString: isoString withString: unicode];
            } while (TRUE); //*** Loop until we hit the NSNotFound
        
            return dataString;
        }
        @end
        

        【讨论】:

          【解决方案12】:

          如果您将字符实体引用作为字符串,例如@"2318",您可以使用 strtoul 提取具有正确 unicode 字符的重新编码的 NSString;

          NSString *unicodePoint = @"2318"
          unichar iconChar = (unichar) strtoul(unicodePoint.UTF8String, NULL, 16);
          NSString *recoded = [NSString stringWithFormat:@"%C", iconChar];
          NSLog(@"recoded: %@", recoded");
          // prints out "recoded: ⌘"
          

          【讨论】:

            【解决方案13】:

            Swift 3 版本的 Jugale 的回答

            extension String {
                static private let mappings = ["&quot;" : "\"","&amp;" : "&", "&lt;" : "<", "&gt;" : ">","&nbsp;" : " ","&iexcl;" : "¡","&cent;" : "¢","&pound;" : " £","&curren;" : "¤","&yen;" : "¥","&brvbar;" : "¦","&sect;" : "§","&uml;" : "¨","&copy;" : "©","&ordf;" : " ª","&laquo" : "«","&not" : "¬","&reg" : "®","&macr" : "¯","&deg" : "°","&plusmn" : "±","&sup2; " : "²","&sup3" : "³","&acute" : "´","&micro" : "µ","&para" : "¶","&middot" : "·","&cedil" : "¸","&sup1" : "¹","&ordm" : "º","&raquo" : "»&","frac14" : "¼","&frac12" : "½","&frac34" : "¾","&iquest" : "¿","&times" : "×","&divide" : "÷","&ETH" : "Ð","&eth" : "ð","&THORN" : "Þ","&thorn" : "þ","&AElig" : "Æ","&aelig" : "æ","&OElig" : "Œ","&oelig" : "œ","&Aring" : "Å","&Oslash" : "Ø","&Ccedil" : "Ç","&ccedil" : "ç","&szlig" : "ß","&Ntilde;" : "Ñ","&ntilde;":"ñ",]
            
                func stringByDecodingXMLEntities() -> String {
            
                    guard let _ = self.range(of: "&", options: [.literal]) else {
                        return self
                    }
            
                    var result = ""
            
                    let scanner = Scanner(string: self)
                    scanner.charactersToBeSkipped = nil
            
                    let boundaryCharacterSet = CharacterSet(charactersIn: " \t\n\r;")
            
                    repeat {
                        var nonEntityString: NSString? = nil
            
                        if scanner.scanUpTo("&", into: &nonEntityString) {
                            if let s = nonEntityString as? String {
                                result.append(s)
                            }
                        }
            
                        if scanner.isAtEnd {
                            break
                        }
            
                        var didBreak = false
                        for (k,v) in String.mappings {
                            if scanner.scanString(k, into: nil) {
                                result.append(v)
                                didBreak = true
                                break
                            }
                        }
            
                        if !didBreak {
            
                            if scanner.scanString("&#", into: nil) {
            
                                var gotNumber = false
                                var charCodeUInt: UInt32 = 0
                                var charCodeInt: Int32 = -1
                                var xForHex: NSString? = nil
            
                                if scanner.scanString("x", into: &xForHex) {
                                    gotNumber = scanner.scanHexInt32(&charCodeUInt)
                                }
                                else {
                                    gotNumber = scanner.scanInt32(&charCodeInt)
                                }
            
                                if gotNumber {
                                    let newChar = String(format: "%C", (charCodeInt > -1) ? charCodeInt : charCodeUInt)
                                    result.append(newChar)
                                    scanner.scanString(";", into: nil)
                                }
                                else {
                                    var unknownEntity: NSString? = nil
                                    scanner.scanUpToCharacters(from: boundaryCharacterSet, into: &unknownEntity)
                                    let h = xForHex ?? ""
                                    let u = unknownEntity ?? ""
                                    result.append("&#\(h)\(u)")
                                }
                            }
                            else {
                                scanner.scanString("&", into: nil)
                                result.append("&")
                            }
                        }
            
                    } while (!scanner.isAtEnd)
            
                    return result
                }
            }
            

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2011-06-22
              • 1970-01-01
              • 2014-11-17
              • 1970-01-01
              相关资源
              最近更新 更多