Swift中的反斜杠

3lxsmp7m  于 2023-04-10  发布在  Swift
关注(0)|答案(5)|浏览(116)

我想取消用户输入字符串中的反斜杠,以便将它们用于正则表达式替换。
使用NSRegularExpression.escapedTemplate(for: "\\n")可以很容易地转义反斜杠。这将返回预期的"\\\\n"。但是我如何将它们向后转换,例如,像\\n(反斜杠+ n)到\n(返回)?

pvcm50d1

pvcm50d11#

我不认为这是可以自动完成的,但是,因为Swift中只有少数转义字符,你可以把它们放入一个数组中,循环遍历它们,然后用未转义的版本替换所有示例。下面是我做的一个String扩展:

extension String {
    var unescaped: String {
        let entities = ["\0", "\t", "\n", "\r", "\"", "\'", "\\"]
        var current = self
        for entity in entities {
            let descriptionCharacters = entity.debugDescription.characters.dropFirst().dropLast()
            let description = String(descriptionCharacters)
            current = current.replacingOccurrences(of: description, with: entity)
        }
        return current
    }
}

要使用它,只需访问属性即可。例如,

print("Hello,\\nWorld!".unescaped)

将打印

Hello,
World!
mgdq6dx1

mgdq6dx12#

我改进了@kabiroberai的代码,使其功能更强大,并删除了剩余的单反斜杠。

extension String {
    var unescaped: String {
        let entities = ["\0": "\\0",
                        "\t": "\\t",
                        "\n": "\\n",
                        "\r": "\\r",
                        "\"": "\\\"",
                        "\'": "\\'",
                        ]

        return entities
            .reduce(self) { (string, entity) in
                string.replacingOccurrences(of: entity.value, with: entity.key)
            }
            .replacingOccurrences(of: "\\\\(?!\\\\)", with: "", options: .regularExpression)
            .replacingOccurrences(of: "\\\\", with: "\\")
    }
}

更新

我发现我以前的代码在某些情况下不能正确地取消转义。
所以,我更新了我的生产代码。下面是我使用的最新代码。我不确定我是否真的需要做这个复杂的过程,但现在它似乎工作得更好了。

var unescaped: String {
    let entities = ["\0": "0",
                    "\t": "t",
                    "\n": "n",
                    "\r": "r",
                    "\"": "\"",
                    "\'": "'",
                    ]

    return entities
        .mapValues { try! NSRegularExpression(pattern: "(?<!\\\\)(?:\\\\\\\\)*(\\\\" + $0 + ")") }
        .reduce(self) { (string, entity) in
            entity.value.matches(in: string, range: string.nsRange)
                .map { $0.range(at: 1) }
                .reversed()
                .reduce(string) { ($0 as NSString).replacingCharacters(in: $1, with: entity.key) }
        }
}
cdmah0mi

cdmah0mi3#

下面是我的转义和未转义字符串

let given =     "{\n\t\"test\": \"this 😃 \\ \",\n\r\t\"\'testing\': 1\r\n}\\ \0 \\"
let expected = #"{\n\t\"test\": \"this 😃 \\ \",\n\r\t\"\'testing\': 1\r\n}\\ \0 \\"#
let expectedAscii = #"{\n\t\"test\": \"this \u{0001F603} \\ \",\n\r\t\"\'testing\': 1\r\n}\\ \0 \\"#

extension String {
    private static let escapedChars = [
        (#"\0"#, "\0"),
        (#"\t"#, "\t"),
        (#"\n"#, "\n"),
        (#"\r"#, "\r"),
        (#"\""#, "\""),
        (#"\'"#, "\'"),
        (#"\\"#, "\\")
    ]
    var escaped: String {
        self.unicodeScalars.map { $0.escaped(asASCII: false) }.joined()
    }
    var asciiEscaped: String {
        self.unicodeScalars.map { $0.escaped(asASCII: true) }.joined()
    }
    var unescaped: String {
        var result: String = self
        String.escapedChars.forEach {
            result = result.replacingOccurrences(of: $0.0, with: $0.1)
        }
        return result
    }
}

print(expected == given.escaped)
print(expectedAscii == given.asciiEscaped)
print(given.escaped.unescaped == given)
print(expected.unescaped == given)
print(expected.unescaped.escaped == expected)
btqmn9zl

btqmn9zl4#

我觉得这个最简单的方法就是用stringByReplacingOccurrencesOfString

let input = "My name is \\n and \\n"
let firstmod = input.stringByReplacingOccurrencesOfString("\\n", withString: "\n", options: [], range: nil)

Input : "My name is \\n and \\n"
Output: "My name is \n and \n"
beq87vna

beq87vna5#

没有一个答案对我有效,以下是对我有效的:

extension String {

    var unescaped: String {
        guard let convertedString = (self as NSString).mutableCopy() as? NSMutableString else {
            return self
        }
        CFStringTransform(convertedString, nil, NSString(string: "Any-Hex/Java"), true)
        return String(convertedString)
    }
}

相关问题