Created
March 18, 2024 14:50
-
-
Save glukianets/e97f883a1170a1586e2d05ecec97f8c0 to your computer and use it in GitHub Desktop.
A simple extension to unescape strings that were erroneusly double-escaped for JSON
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
extension String { | |
private static let excapesRegex: Regex = /\\(?<a>[bfnrtv0])|\\(?<x>x\H{2})|(?<u>(?:\\u\H{4})+)/ | |
struct InvalidEscapeSequenceError: Error { | |
let value: Substring | |
} | |
func unescaped() throws -> String { | |
try self.replacing(Self.excapesRegex) { match in | |
if let a = match.a { | |
switch a { | |
case "b": | |
"\u{8}" | |
case "f": | |
"\u{C}" | |
case "n": | |
"\n" | |
case "r": | |
"\r" | |
case "t": | |
"\t" | |
case "v": | |
"\u{B}" | |
case "0": | |
"\0" | |
default: | |
String(a) | |
} | |
} else if let x = match.x { | |
String(UInt8(x, radix: 16)!) // regex guarantees valid hex | |
} else if let u = match.u { | |
u.split(separator: "\\u") | |
.map { unichar($0, radix: 16)! /*regex guarantees valid hex*/ } | |
.withUnsafeBufferPointer { String(utf16CodeUnits: $0.baseAddress!, count: $0.count) } | |
} else { | |
throw InvalidEscapeSequenceError(value: match.0) | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment