Быстрое регулярное выражение - неожиданное поведение с возвратом каретки `\ r` - PullRequest
1 голос
/ 13 марта 2020

У меня есть строка открытого / закрытого ключа RSA в Swift, из которой я хочу удалить комментарии с помощью регулярных выражений. Фактическая строка ключа содержит специальные комбинации символов, такие как \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

Но когда я удаляю два символа возврата каретки, результат, как и ожидалось, без черточек. Что здесь не так?

Ответы [ 2 ]

1 голос
/ 13 марта 2020

Ваше регулярное выражение в порядке. Проблема в том, что 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?

См. регулярное выражение регулярных выражений

0 голосов
/ 13 марта 2020

В качестве альтернативы

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?
...