我希望能够将用户输入字符串中的反斜杠进行转义,以便用于正则表达式替换。
使用NSRegularExpression.escapedTemplate(for: "\\n")
很容易就可以转义反斜杠。这会返回所期望的"\\\\n"
。但是,我该如何进行反向转换,例如,将\\n
(反斜杠+n)转换为\n
(回车)呢?
我不认为这可以自动完成,但是由于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!
这里是关于字符串的转义和非转义
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)
我认为最简单的方法是使用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"
\\n
转换为\n
,\\t
转换为\t
。 - 1024jp\r
、\"
和\\
怎么办呢?好吧,这是一种替换所有这些组合的方法... - 1024jpextension 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) }
}
}
.replacingOccurrences(...)
是用来干什么的?你的解决方案好像没有它们也能正常工作。 - maxkonovalovType of expression is ambiguous without more context
- Vyacheslav对我来说,这些答案都没有起作用,以下是让我成功的方法:
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)
}
}
print("X\\u000AY\\nZ".unescaped)
只将第一个转义变成了换行符,但不是第二个。(如果它起作用的话,X、Y和Z都会输出为单独的行。但Y和Z在一行上,由字面上的字符\n
分隔。)这实际上与“Any-Hex”转换的文档一致。它只指示Unicode代码点转义,而不是其他类型。虽然很有趣,但我以前从未听说过这个函数。 - ecp