【问题标题】:Swift regular expression - unexpected behavior with carriage return `\r`Swift 正则表达式 - 回车 `\r` 的意外行为
【发布时间】:2020-03-13 20:35:25
【问题描述】:

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

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

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

【问题讨论】:

  • @Larme \n 字符串模式(所谓的正则表达式转义序列)匹配换行符,与"\n" 相同,换行符匹配自身。

标签: swift regex carriage-return nsregularexpression


【解决方案1】:

你的正则表达式很好。问题是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

【讨论】:

  • 完美,非常感谢这两种解决方案!以及更简洁的正则表达式。
【解决方案2】:

或者

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?

【讨论】:

    猜你喜欢
    • 2012-07-16
    • 1970-01-01
    • 1970-01-01
    • 2013-01-14
    • 2017-02-27
    • 2013-09-29
    • 1970-01-01
    • 1970-01-01
    • 2013-11-15
    相关资源
    最近更新 更多