正则表达式可在在线工具中使用,但与 NSRegularExpression 不一致
regex works in online tool but doesn't agree with NSRegularExpression
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 中不起作用。
我该怎么做?
基于 Larme 的评论:
in Swift, \
(double back slash) in a String is for "having a ``, as you see in the error, you have (?<!\)
, but it means then that you are escaping the closing )
, so you have a missing closing )
. I'd say that you should write then "(?<!\\)\n"
?
我终于弄清楚发生了什么以及如何解决它。
问题是反斜杠。
在Swift中,双引号内的反斜杠将被视为转义序列,像这样
// won't compile
// error: Invalid escape sequence in literal
let regex = try NSRegularExpression.init(pattern: "(?<!\)\n")
如果我们再添加一个反斜杠,可以吗?
不,因为这 2 个反斜杠将被视为即将结束的单个 转义字符。
// compile but get a runtime error
let regex = try NSRegularExpression.init(pattern: "(?<!\)\n")
因此出现运行时错误
NSRegularExpression did not recognize the pattern correctly.
Error Domain=NSCocoaErrorDomain Code=2048 "The value “(?<!\)
” is invalid." UserInfo={NSInvalidValue=(?<!\)
为了表明我们需要的是文字反斜杠,实际上我们需要 4 个反斜杠
let regex = try NSRegularExpression.init(pattern: "(?<!\\)\n")
前两个反斜杠代表一个转义字符,后两个代表一个文字反斜杠。
这些好像很麻烦
更好的方法
幸运的是,从Swift5开始,我们可以用一对#来做到这一点
// works like in online tool
let regex = try NSRegularExpression.init(pattern: "(?<!\)\n")
另一件事
值得注意的是,正则表达式的初始化并不是唯一需要特殊处理的东西
// withTemplate
print(regex.stringByReplacingMatches(in: string, options: [], range: NSMakeRange(0, string.count), withTemplate: #"\n"#))
// As a comparison, this is OK
print(string.replacingOccurrences(of: "\n", with: "\N"))
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 中不起作用。
我该怎么做?
基于 Larme 的评论:
in Swift,
\
(double back slash) in a String is for "having a ``, as you see in the error, you have(?<!\)
, but it means then that you are escaping the closing)
, so you have a missing closing)
. I'd say that you should write then"(?<!\\)\n"
?
我终于弄清楚发生了什么以及如何解决它。
问题是反斜杠。
在Swift中,双引号内的反斜杠将被视为转义序列,像这样
// won't compile
// error: Invalid escape sequence in literal
let regex = try NSRegularExpression.init(pattern: "(?<!\)\n")
如果我们再添加一个反斜杠,可以吗?
不,因为这 2 个反斜杠将被视为即将结束的单个 转义字符。
// compile but get a runtime error
let regex = try NSRegularExpression.init(pattern: "(?<!\)\n")
因此出现运行时错误
NSRegularExpression did not recognize the pattern correctly.
Error Domain=NSCocoaErrorDomain Code=2048 "The value “(?<!\)
” is invalid." UserInfo={NSInvalidValue=(?<!\)
为了表明我们需要的是文字反斜杠,实际上我们需要 4 个反斜杠
let regex = try NSRegularExpression.init(pattern: "(?<!\\)\n")
前两个反斜杠代表一个转义字符,后两个代表一个文字反斜杠。
这些好像很麻烦
更好的方法
幸运的是,从Swift5开始,我们可以用一对#来做到这一点
// works like in online tool
let regex = try NSRegularExpression.init(pattern: "(?<!\)\n")
另一件事
值得注意的是,正则表达式的初始化并不是唯一需要特殊处理的东西
// withTemplate
print(regex.stringByReplacingMatches(in: string, options: [], range: NSMakeRange(0, string.count), withTemplate: #"\n"#))
// As a comparison, this is OK
print(string.replacingOccurrences(of: "\n", with: "\N"))