Swift - 移除单个反斜杠

11

这也许是一个愚蠢的问题,但我对swift很新,实际上我无法解决它。

我有一个API,它返回URL作为字符串“http:\/\/xxx<\/strong>”。 我不知道如何以此格式存储从API返回的URL。由于反斜杠,我不能将其存储到变量中。

来自Apple文档:

...字符串不能包含未转义的反斜杠(\),...

是否有任何方法可以存储这样的字符串,或者如何删除这些单个反斜杠,或如何处理这个问题?

感谢您的每一个建议。


反斜杠在哪里? - matt
抱歉,我没有注意到反斜杠消失了。我已经将它们添加到URL中。 - marysmech
使用它: myString.replacingOccurrences(of: "\/", with: "\",options: .literal, range: nil) - Masoud Roosta
你可以使用 #"带有反斜杠的字符串"# - onmyway133
6个回答

9

你可以直接替换那些反斜杠,例如:

let string2 = string1.stringByReplacingOccurrencesOfString("\\", withString: "")

或者,为了避免在正常字符串字面值中反斜杠需要用另一个反斜杠转义的混淆,我们可以使用扩展字符串分隔符#""#

let string2 = string1.stringByReplacingOccurrencesOfString(#"\"#, withString: "")

但是,如果可能的话,你真的应该修复返回这些反斜杠的API,因为显然这是不正确的。那段代码的作者显然误认为必须对正斜杠进行转义,但实际上并非如此。

总之,应该修复API以便不插入这些反斜杠,但在此之前,您可以使用上述方法来删除可能出现的任何反斜杠。


在下面的评论讨论中,关于字符串中的反斜杠似乎存在巨大的困惑。所以,让我们退一步,讨论“字符串字面量”。正如文档所说,字符串字面量是:

您可以将预定义的String值作为字符串字面量包含在代码中。字符串字面量是由一对双引号("")括起来的固定文本字符序列。

注意,字符串字面值只是您代码中特定固定字符序列的表示。但是,这不应与底层的String对象本身混淆。字符串字面值和底层的String对象之间的关键区别在于,字符串字面值允许使用反斜杠作为“转义”字符,用于表示特殊字符(或进行字符串插值)。正如文档所述
字符串字面量可以包含以下特殊字符:
  • 转义的特殊字符 \0(空字符)、\\(反斜杠)、\t(水平制表符)、\n(换行符)、\r(回车符)、\"(双引号)和 \'(单引号)
  • 任意 Unicode 标量,写作 \u{n},其中 n 是一个 1 到 8 位十六进制数,表示一个有效的 Unicode 代码点
所以,你是正确的,在字符串字面量中,正如你引用的摘录所指出的那样,你不能有未转义的反斜杠。因此,每当你想要在字符串字面量中表示单个反斜杠时,你就使用 \\ 来表示它。
因此,上面的 stringByReplacingOccurrencesOfString 的意思是“查找 string1 中的所有单个反斜杠,并将它们替换为一个空字符串(即删除反斜杠)”。
考虑一下:
let string1 = "foo\\bar"

print(string1)                    // this will print "foo\bar"
print(string1.characters.count)   // this will print "7", not "8"

let string2 = string1.stringByReplacingOccurrencesOfString("\\", withString: "")

print(string2)                    // this will print "foobar"
print(string2.characters.count)   // this will print "6"

有点令人困惑的是,如果您在“调试”面板的“变量”视图或游乐场中查看string1,它将显示一个字符串文字表示(即反斜杠将显示为"\\")。但不要困惑。当您在字符串文字中看到\\时,实际上实际字符串中只有一个反斜杠。但是,如果您print该值或查看实际字符,则字符串本身中仅有一个反斜杠。
简而言之,请不要混淆字符串文字中反斜杠的转义(例如,stringByReplacingOccurrencesOfString的参数)和基础字符串中存在的单个反斜杠。

1
不,string1.stringByReplacingOccurrencesOfString("\\", withString: "") 确实会用 "" 替换单个反斜杠的出现。在字符串字面量中指定“单个反斜杠”的方式是 "\"。 - Rob
是的,如果我在本地变量中测试它,我可以添加额外的反斜杠。但是,如果我从API下载带有反斜杠的字符串,我仍然看不到如何处理像“http://”这样的字符串。 - marysmech
非常好。顺便说一下,如果API的东西仍在进行中,那么就让他们一开始就不包括那些反斜杠。显然,设计这个的人错误地认为方案中的斜杠字符需要转义,但实际上并不需要。您必须转义反斜杠字符,但不需要转义正斜杠字符。最好解决问题,而不是围绕一个有缺陷的接口进行编程。 - Rob
我遇到了同样的问题。我编写了一个插入查询,但由于单个反斜杠而失败。 查询是: "insert into Users (emailId, password) values ('ios@gmail.com', 'Nunnumann@1');" 但在运行时它显示为:"insert into Users (emailId, password) values ('ios@gmail.com', 'Nunnumann@1');" 有什么解决方法吗? - i_Intiution
@i_Intiution - 首先,你根本不应该在字符串字面值中使用反斜杠来转义 ' 字符,因此这个问题有些无关紧要。其次,如果在进行SQL操作时,应该避免通过构建字符串来插入值,而是应该使用 ? 占位符,例如 insert into Users (emailId, password) values (?, ?) 然后通过SQLite API将值绑定到这两个占位符中。 - Rob
显示剩余11条评论

4

在尝试将对象编码为JSON时,我发现我也遇到了同样的问题。根据你是否正在使用较新的JSONEncoder类来解析JSON,并且你支持iOS 13的最小版本,你可以使用.withoutEscapingSlashes输出格式:

let encoder = JSONEncoder()
encoder.outputFormatting = .withoutEscapingSlashes

try encoder.encode(yourJSONObject)

3
请查看以下代码。
let jsonStr = "[{\"isSelected\":true,\"languageProficiencies\":[{\"isSelected\":true,\"name\":\"Advance\"},{\"isSelected\":false,\"name\":\"Proficient\"},{\"isSelected\":false,\"name\":\"Basic\"},{\"isSelected\":false,\"name\":\"Below Basic\"}],\"name\":\"English\"},{\"isSelected\":false,\"languageProficiencies\":[{\"isSelected\":false,\"name\":\"Advance\"},{\"isSelected\":false,\"name\":\"Proficient\"},{\"isSelected\":false,\"name\":\"Basic\"},{\"isSelected\":false,\"name\":\"Below Basic\"}],\"name\":\"Malay\"},{\"isSelected\":false,\"languageProficiencies\":[{\"isSelected\":false,\"name\":\"Advance\"},{\"isSelected\":false,\"name\":\"Proficient\"},{\"isSelected\":false,\"name\":\"Basic\"},{\"isSelected\":false,\"name\":\"Below Basic\"}],\"name\":\"Chinese\"},{\"isSelected\":false,\"languageProficiencies\":[{\"isSelected\":false,\"name\":\"Advance\"},{\"isSelected\":false,\"name\":\"Proficient\"},{\"isSelected\":false,\"name\":\"Basic\"},{\"isSelected\":false,\"name\":\"Below Basic\"}],\"name\":\"Tamil\"}]"
let convertedStr = jsonStr.replacingOccurrences(of: "\\", with: "", options: .literal, range: nil)
print(convertedStr)

这个不起作用。 - Nicolai Harbo

3
我用以下代码解决了这个问题:
let convertedStr = jsonString.replacingOccurrences(of: "\\/", with: "/") 

我将其更改为myString.replacingOccurrences(of: "\/", with: "\"),它可以正常工作。 - Masoud Roosta

2

为了删除单个反斜杠,请尝试使用以下方法

let replaceStr = backslashString.replacingOccurrences(of: "\"", with: "")

4
如果您添加了此代码,所有双引号都将被替换。 - Madhu Avinash

1

通过添加额外的反斜杠在字符串中包含反斜杠。


谢谢您的评论。我不知道如何添加反斜杠,因为我无法执行 var str = "http:\/\/",或者我漏掉了什么? - marysmech
现在你正在添加一个转义字符加上一个正斜杠。你可以通过添加转义字符后跟反斜杠本身(转义字符)来添加反斜杠。var str="http:\\www." - Vincent
说起来,对于一个网站,你需要斜杠。因此,你可以轻松地分配:var str = "http://www.ebay.nl" - Vincent

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接