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?
或者
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?
我在 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?
或者
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?