Swift 正则表达式 - 回车的意外行为 return `\r`

Swift regular expression - unexpected behavior with carriage return `\r`

我在 Swift 中有一串 public/private RSA 密钥,我想使用正则表达式从中删除注释。实际的键字符串包含特殊字符组合,例如 \r\n 用于回车 return + 换行。这是一个例子:

let publicKey = "-----BEGIN RSA PUBLIC KEY-----\n0123456789\r\n0123456789\r\nabcdefgh\n-----END RSA PUBLIC KEY-----"
let regex = try! NSRegularExpression(pattern: "(\n)?-* ?(BEGIN|END) ((PRIVATE RSA|PUBLIC RSA)|(RSA PRIVATE|RSA PUBLIC)|(PRIVATE|PUBLIC)) KEY ?-*(\n)?", options: NSRegularExpression.Options.caseInsensitive)
let range = NSMakeRange(0, publicKey.count)
print(regex.stringByReplacingMatches(in: publicKey, options: [], range: range, withTemplate: ""))

打印结果为

0123456789
0123456789
abcdefgh--

但应该是

0123456789
0123456789
abcdefgh

但是当我删除两个回车 return 字符时,结果与预期的一样,没有破折号。这里出了什么问题?

你的正则表达式没问题。问题是 publicKey.count 会将像 \r\n 这样的行尾算作一个字符。

您可以使用

解决问题
let range = NSMakeRange(0, publicKey.utf16.count)

或者,简单地使用 .replacingOccurrences.regularExpression 选项:

let publicKey = "-----BEGIN RSA PUBLIC KEY-----\n0123456789\r\n0123456789\r\nabcdefgh\n-----END RSA PUBLIC KEY-----"
let regex = "(?i)(\n)?-* ?(BEGIN|END) ((PRIVATE RSA|PUBLIC RSA)|(RSA PRIVATE|RSA PUBLIC)|(PRIVATE|PUBLIC)) KEY ?-*(\n)?"
print( publicKey.replacingOccurrences(of: regex, with: "", options: [.regularExpression]) )
// => 0123456789
//    0123456789
//    abcdefgh

如果您想缩短模式,请使用

(?i)\n?-* ?(?:BEGIN|END) (?:(?:PRIVATE|PUBLIC)(?: RSA)?|RSA (?:PRIVATE|PUBLIC)) KEY ?-*\n?

regex online demo

或者

let publicKey = "-----BEGIN RSA PUBLIC KEY-----\n0123456789\r\n0123456789\r\nabcdefgh\n-----END RSA PUBLIC KEY-----"
let result = publicKey.replacingOccurrences(of: "\s?-+[^-]+-+\s?", with: "", options: .regularExpression)
print(result)

模式是:

  • 可选空格\s?
  • 一个或多个破折号 -+
  • 一个或多个非破折号[^-]+
  • 一个或多个破折号 -+
  • 可选空格\s?