#html #swift
Вопрос:
Я хочу иметь возможность декодировать строку в формате x20, x3c, которую я получаю из HTML, в Swift. Я попробовал это на python и смог сделать это с помощью этого кода
soupData = dom
encodedSoupData = soupData.encode('utf8')
soupData = encodedSoupData.decode('unicode_escape')
где dom
x20x20backgroundx2Dsizex3Ax20Contain
Приведенный выше код возвращает
background-size: Contain
То, что я сделал в Swift сейчас, это:
- Преобразуйте эту строку в
Data
кодер utf8. - Попробуйте декодировать данные обратно
String
с помощью декодера unicode.
До сих пор у меня ничего не получалось. Любая помощь была бы очень признательна. Спасибо!
Комментарии:
1. Контролируете ли вы источник этих данных? Насколько я помню, это нестандартная схема кодирования. Было бы лучше просто иметь правильную строку Юникода с самого начала
2. К сожалению, я этого не делаю 🙁
Ответ №1:
После долгих экспериментов я, наконец, смог решить этот вопрос.
Во — первых, мы добавляем расширение String
для декодирования символов Юникода:
extension String {
var decodingUnicodeCharacters: String { applyingTransform(.init("Hex-Any"), reverse: false) ?? "" }
}
Затем мы создаем регулярное выражение с 2 группами захвата-
- Первая группа-это экранирующий символ x
- Вторая группа-это 2 буквенно-цифровых символа после x. (В моем примере буквы написаны в верхнем регистре.
let pattern = #"(\x)?([0-9A-F]{2})"#
guard let regex = try? NSRegularExpression(pattern: pattern, options: .anchorsMatchLines) else { return }
Затем мы находим длину совпадающей строки, а затем используем stringByReplacingMatches
вкл NSRegularExpression
., чтобы заменить совпадения в диапазоне шаблоном.
Шаблон-это то, что становится интересным. После долгих исследований я обнаружил, что преобразование строки xxx в u00XX является единственным шаблоном, который помогает в декодировании строки.
let testString: String = #"x20x20backgroundx2Dsizex3Ax20Contain"#
let stringRange = NSRange(location: 0, length: testString.utf16.count)
let result = regex.stringByReplacingMatches(in: testString, range: stringRange, withTemplate: #"\u00$2"#)
Теперь просто нанесите decodingUnicodeCharacters
на result
строку.
print(result.decodingUnicodeCharacters) //Outputs: " background-size: Contain"