do {
// initialization failed, looks like I can not use "\\" here
let regex = try NSRegularExpression.init(pattern: "(?<!\\)\n")
let string = """
aaabbb
zzz
"""
// expect "aaabbb\nzzz"
print(regex.stringByReplacingMatches(in: string, options: [], range: NSMakeRange(0, string.count), withTemplate: "\\n"))
} catch let error {
print(error)
}
在这里,我想将字符串中的“\n”替换为“\n”,但在开头就失败了,错误消息为
// NSRegularExpression did not recognize the pattern correctly.
Error Domain=NSCocoaErrorDomain Code=2048 "The value “(?<!\)
” is invalid." UserInfo={NSInvalidValue=(?<!\)
}
这个正则表达式已经在regular expression 101中测试过了,所以它是正确的,只是由于某种原因在Swift中不起作用。
我该怎么做?
1条答案
按热度按时间a0zr77ik1#
根据Larme的评论:
在Swift中,字符串中的
\
(双反斜杠)表示“有一个”,正如你在错误中看到的,你有(?<!\)
,但它意味着你正在转义结束的)
,所以你有一个丢失的结束的)
。我想你应该写为then"(?<!\\\\)\n"
?我终于弄明白了是怎么回事,以及如何解决它。
问题是反斜杠。
在Swift中,双引号内的反斜杠将被视为转义序列,如下所示
如果我们再加一个反斜杠,它是工作吗?
否,因为这两个反斜杠将被视为即将结束的单个转义符)。
因此出现运行时错误
为了说明我们需要的是一个反斜杠,我们实际上需要4个反斜杠
前两个反斜杠表示转义字符,后两个反斜杠表示一个文字反斜杠。
这些看起来很麻烦。
更好的方法
幸运的是,从Swift 5开始,我们可以使用一对#来实现这一点
另一件事
值得注意的是,正则表达式的初始化并不是唯一需要特殊处理的事情