RegEx работает онлайн в RegexR, но не может инициализироваться на iOS в NSRegularExpression - PullRequest
2 голосов
/ 07 марта 2019

У меня есть регулярное выражение, предназначенное для извлечения git URL из определения CocoaPods.

Вводимый текст выглядит следующим образом:

pod 'Alamofire', :git => 'https://github.com/Alamofire/Alamofire.git', :branch => 'dev'

Регулярное выражение выглядит следующим образом:

(?<=('Alamofire'.*:git => '))[A-Za-z:/\.]+(?=('{1}))

Это регулярное выражение правильно работает с RegexR, см. здесь , однако при попытке инициализировать NSRegularExpression с ним выдается ошибка с кодом 2048, говорящим, что шаблон недействителен. Обычно это связано с отсутствием побегов, но здесь их нет. Я не могу понять, в чем проблема, даже после просмотра документов регулярного выражения ICU, который является механизмом, который использует iOS.

Любые идеи были бы хорошо приняты, TIA.

Ответы [ 2 ]

0 голосов
/ 07 марта 2019

Вы не можете использовать шаблоны неизвестной длины в шаблонах с задним числом с регулярными выражениями ICU.Ваш образец содержит .* в поиске сзади, поэтому он является недопустимым ICU regexp (см. Длину возможных строк, соответствующих шаблону просмотра, не должно быть неограниченным (нет * или+ операторов.) ICU смотреть за частью документации).

Существует два способа:

  • Заменить .* на .{0,x}, где x - максимальное число символов, которое вы ожидаете отделить от левой фигуры от правойВ соответствии с шаблоном ICU регулярные выражения позволяют определять квантификатор , ограничивающий (или интервал , range ), поэтому их также называют "ограниченная ширина")
  • Обновите шаблон, чтобы использовать шаблон потребления вместо обходных путей, оберните часть, которую необходимо извлечь, с помощью скобок и измените код, чтобы получить значение группы 1.

ЗдесьПодход 2, который рекомендуется:

let str = "pod 'Alamofire', :git => 'https://github.com/Alamofire/Alamofire.git', :branch => 'dev'"
let rng = NSRange(location: 0, length: str.utf16.count)
let regex = try! NSRegularExpression(pattern: "'Alamofire'.*:git\\s*=>\\s*'([^']+)'")
let matches = regex.matches(in: str, options: [], range: rng)
let group1 = String(str[Range(matches[0].range(at: 1), in: str)!])
print(group1) // => https://github.com/Alamofire/Alamofire.git

См. Демонстрационный пример regex , выделенная зеленым цветом подстрока - это значение, которое вы получаете в группе 1.

Детали шаблона:

  • 'Alamofire' - буквенная строка
  • .* - любые 0+ символов, кроме символов разрыва строки, как можно больше (замените на .*?, чтобы соответствовать как можно меньшему числу символов)возможно)
  • :git - буквальная подстрока
  • \s*=>\s* - =>подстрока, заключенная в 0+ пробелов
  • '([^']+)' - ', затем группа захвата # 1, соответствующая 1+ символам, отличным от ', а затем ' char.
0 голосов
/ 07 марта 2019

Проверочное утверждение в NSRegularExpression ограничено и не поддерживает в нем операторы * или +:

, то есть часть .* в (?<=('Alamofire'.*:git => '))

(? <= ...) </p>

Утверждаемое утверждение.Истинно, если шаблон в скобках соответствует тексту, предшествующему текущей позиции ввода, причем последний символ совпадения является входным символом непосредственно перед текущей позицией.Не меняет позицию ввода.Длина возможных строк, соответствующих шаблону поиска, не должна быть неограниченной (без * или + операторов.)

Ссылка: https://developer.apple.com/documentation/foundation/nsregularexpression

Вы просто хотитешаблон url так просто соответствует только этой части и в первую очередь не нуждается в проверочном утверждении.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...