¿Cómo decodificar cadenas que incluyen literales utf8 como ”\xc3\xa6” en Swift?
Pregunta de seguimiento a mi anterior hilo sobre literales UTF-8:
Se estableció que se pueden decodificar literales UTF-8 de cadenas de esta manera que incluyen exclusivamente literales UTF-8:
let s = "\xc3\xa6"
let bytes = s
.components(separatedBy: "\x")
// components(separatedBy:) produciría una cadena vacía como primer elemento
// porque la cadena comienza con "\x". Lo omitimos
.dropFirst()
.compactMap { UInt8($0, radix: 16) }
if let decoded = String(bytes: bytes, encoding: .utf8) {
print(decoded)
} else {
print("¡La secuencia UTF8 era inválida!")
}
Sin embargo, esto solo funciona si la cadena solo contiene literales UTF-8. Como estoy obteniendo una lista de nombres de Wi-Fi que contienen estos literales UTF-8, ¿cómo decodifico toda la cadena?
Ejemplo:
let s = "Este es un nombre de Wi-Fi \xc3\xa6 que incluye literales UTF-8 \xc3\xb8"
Con el resultado esperado:
print(s)
Este es un nombre de Wi-Fi æ que incluye literales UTF-8 ø
En Python hay una solución simple para esto:
contents = source_file.read()
uni = contents.decode('unicode-escape')
enc = uni.encode('latin1')
dec = enc.decode('utf-8')
¿Existe una manera similar de decodificar estas cadenas en Swift 5?
davy.ai
Sí, puedes usar el método
String.decodeCString(_:as:repairingInvalidCodeUnits:)
de Swift para decodificar la cadena.Aquí está el código actualizado:
La propiedad
utf8CString
convierte la cadena en una matriz nula-terminada de bytes UTF-8, que es el formato requerido pordecodeCString(_:as:repairingInvalidCodeUnits:)
. El parámetrorepairingInvalidCodeUnits
se establece entrue
para corregir automáticamente cualquier unidad de código UTF-8 inválida. El resultado se convierte de nuevo en unaString
.Ten en cuenta que este enfoque supone que las secuencias de escape ya están formateadas correctamente para la codificación UTF-8. Si no es así, es posible que debas procesar la cadena previamente para convertirlas antes de usar este método.