Розшифровка символів HTML у Objective-C / Cocoa Touch


103

Перш за все, я виявив це: Об'єктивний C HTML escape / unescape , але це не працює для мене.

Мої закодовані символи (походять із RSS-каналу, btw) виглядають так: &

Я шукав по всій мережі і знайшов відповідні дискусії, але жодного виправлення для мого конкретного кодування, я думаю, що вони називаються шістнадцятковими символами.


3
Цей коментар через півроку після первинного питання, тому більше для тих, хто натрапляє на це питання, шукаючи відповіді та рішення. Дуже схоже запитання прийшов зовсім недавно , що я відповів stackoverflow.com/questions/2254862 / ... Він використовує RegexKitLite і блоки , щоб зробити пошук і заміну з &#...;в рядку з його еквівалентним характером.
johne

Що конкретно "не працює"? Я не бачу нічого в цьому питанні, що б не було дублікатом цього попереднього питання.
Пітер Хосей

Це десятковий. Шістнадцяткова є 8.
kennytm

Різниця між десятковим і шістнадцятковим є тим, що десятковий є базовим-10, тоді як шістнадцятковим є базовий-16. "38" - різне число у кожній базі; у базі 10 це 3 × 10 + 8 × 1 = тридцять вісім, тоді як у базі-16 - 3 × 16 + 8 × 1 = п'ятдесят шість. Більш високі цифри - це (кратні) вищі сили бази; найнижча ціла цифра - основа 0 (= 1), наступна вища цифра - база 1 (= база), наступна - база ** 2 (= база * база) і т. д. Це є експоненцією на роботі.
Пітер Хосей

Відповіді:


46

Вони називаються посиланнями особи особи . Коли вони приймають форму, &#<number>;вони називаються числовими посиланнями на сутність . В основному, це рядкове представлення байта, яке слід замінити. У разі &#038;, він представляє символ зі значенням 38 у схемі кодування символів ISO-8859-1, яка є &.

Причина, яку потрібно зашифрувати в RSS, - це зарезервований спеціальний символ.

Що вам потрібно зробити, це проаналізувати рядок і замінити об'єкти на байт, що відповідає значенню між &#і ;. Я не знаю жодних чудових способів зробити це в об'єктивному C, але це питання переповнення стека може бути корисною.

Редагувати: з моменту відповіді на це два роки тому є чудові рішення; див. відповідь @Michael Waterfall нижче.


2
+1 Я ось-ось збирався надіслати абсолютно таку ж відповідь (включаючи ті ж посилання, не менше!)
напр. James

"В основному, це рядкове представлення байта, яке слід замінити." Більше схожий на характер. Це текст, а не дані; при перетворенні тексту в дані, символ може займати кілька байтів, залежно від символу та кодування.
Пітер Хосей

Дякую за відповідь. Ви сказали, що "він представляє символ зі значенням 38 у схемі кодування символів ISO-8859-1, що є &". Ви впевнені в цьому? Чи є у вас посилання на таблицю символів такого типу? Бо з того, що я пам’ятаю, це була єдина цитата.
трезник

en.wikipedia.org/wiki/ISO/IEC_8859-1#ISO-8859-1 або просто введіть & # 038; в google.
Метт Бріджес

а як щодо & amp; або & копіювати; символи?
vokilam

162

Перевірте мою категорію NSString щодо HTML . Ось доступні методи:

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

3
Чувак, відмінні функції. Ваш метод stringByDecodingXMLEntities зробив мій день! Дякую!
Брайан Москау

3
Без проблем;) Радий, що Ви вважаєте це корисним!
Водоспад Майкл

4
Після кількох годин пошуку я знаю, що це єдиний спосіб зробити це, що дійсно працює. NSString прострочено для рядкового методу, який може це зробити. Молодці.
Адам Ебербах

1
Я виявив (2) у ліцензії Майкла занадто обмежувальний для мого використання, тому я використав рішення Нікіти. У тому числі три файли з ліцензією Apache-2.0 з інструментарію Google чудово підходять для мене.
Хайме

10
Оновлення коду для ARC було б дуже зручним. Xcode кидає тону помилок ARC та попереджень про нарощування
Matej

52

Той, що Даніель, в основному дуже приємний, і я виправив там кілька питань:

  1. видалено пропускний символ для NSSCanner (інакше пробіли між двома суцільними об'єктами будуть ігноровані

    [сканер setCharactersToBeSkipped: nil];

  2. виправлено аналіз при наявності ізольованих символів "&" (я не впевнений, що є "правильним" висновком для цього, я просто порівняв його з firefox):

напр

    &#ABC DF & B&#39;  & C&#39; 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:@"&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", (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/…
Кайл

Я би двічі палив тебе вгору, якби міг.
Kibitz503

Swift переклад людей все ще відвідують це питання в 2016+: stackoverflow.com/a/35303635/1153630
Макс Chuquimia

46

На прошивці 7, ви можете декодувати символи HTML спочатку за допомогою NSAttributedStringз NSHTMLTextDocumentTypeатрибутом:

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

Декодований атрибутивний рядок тепер відображатиметься як:  & & <> ™ © ♥ ♣ ♠ ♦.

Примітка. Це буде працювати лише в тому випадку, якщо виклик основного потоку.


6
найкраща відповідь, якщо вам не потрібно підтримувати iOS 6 та старші
jcesarmobile

1
ні, не найкраще, якщо хтось хоче його закодувати на bg thread; O
badeleux

4
Це працювало для розшифровки сутності, але воно також переплутало некодований тире.
Андрій

Це вимушено відбувається на головній нитці. Тож ви, мабуть, не хочете цього робити, якщо цього не потрібно.
Кіт Смайлі

Він просто висить на GUI, коли це питання UITableView. Отже, працює неправильно.
Асиф Білал

35

Здається, ніхто не згадує про один з найпростіших варіантів: 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;

І мені довелося включати в проект лише три файли: заголовок, реалізація та GTMDefines.h.


Я включив ці три сценарії, але як я можу ним зараз користуватися?
Борут Томазін

@ borut-t [myString gtm_stringByUnescapingFromHTML]
Микита Рибак

2
Я вирішив включити тільки ці три файли, так що мені потрібно зробити це , щоб зробити його сумісним з дугою: code.google.com/p/google-toolbox-for-mac/wiki/ARC_Compatibility
Хайме

я мушу сказати, що це найпростіше і
найлегше

Я б хотів, щоб я міг змусити це повністю працювати. Начебто пропускає через них багато моїх струн.
Джозеф Торонто

17

Я повинен розмістити це на GitHub чи що-небудь. Це відноситься до категорії NSString, використовує NSScannerдля реалізації та обробляє як шістнадцяткові та десяткові сукупності числових символів, так і звичайні символьні.

Крім того, він обробляє неправильно сформовані рядки (коли у вас є & слідує недійсна послідовність символів) відносно витончено, що виявилося вирішальним у моєму випущеному додатку, який використовує цей код.

- (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-об'єкти, такі як & micro; ... ect ????
чинтхакад

Вам слід уникати використання gotos як його жахливого стилю коду. Ви повинні замінити рядок goto finish;на break;.
оглушення

4

Ось так я це роблю, використовуючи рамку 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;  

}

Сподіваюся, що це комусь допоможе.


4

ви можете використовувати саме цю функцію для вирішення цієї проблеми.

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

2

Ось швидка версія відповіді Walty Yeung :

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
    }
}

1

Насправді чудовий фреймворк MWFeedParser Майкла Водоспаду (згаданий його відповідь) був роздвоєний rmchaara, який оновив його за підтримки ARC!

Ви можете знайти його в Github тут

Це дійсно чудово працює, я використав метод stringByDecodingHTMLEntities і працює бездоганно.


Це виправляє проблеми ARC, але вводить деякі попередження. Я вважаю, що безпечно їх ігнорувати?
Роберт Дж. Клегг

0

Наче потрібне інше рішення! Цей досить простий і досить ефективний:

@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

0

Якщо у вас є посилання Entity Entry Character як рядок, наприклад @"2318", ви можете витягнути перекодований NSString з використанням правильного символу unicode strtoul;

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

0

Швидка версія 3 відповіді Джугале

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
    }
}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.