Струнные вещи
При обсуждении проблемы распознавания строкового сопоставления с образцом первой мыслью, которая приходит в голову, вероятно, будет алгоритм Кнута-Морриса-Пратта. Однако я хотел бы представить более интуитивно понятный метод, основанный на range(of:options:range:locale:)
, который является частью стандартной библиотеки Swift.
Возвращайте первое появление несколько раз, чтобы собрать их все
Если вы обратитесь к документации разработчика Apple, вы найдете это описание функции range(of:options:range:locale:)
:
«Находит и возвращает диапазон первого вхождения заданной строки в заданном диапазоне String с учетом заданных параметров, используя заданный языковой стандарт, если таковой имеется».
Да, он возвращает только первое вхождение. Следовательно, для достижения нашей цели нам нужно построить цикл while
для перебора всех вхождений данной строки в приемнике. Фрагмент ссылки будет похож на следующий блок кода. Обратите внимание, что смещение также добавляется для уменьшения длины диапазона на каждой итерации. Итак, на самом деле позиция каждого цикла в основном основана на верхней границе предыдущей итерации:
Преобразовать индексы в диапазоны
Иногда возврата всех индексов недостаточно для выполнения операций поиска и замены всех при редактировании текста. Следовательно, помощник transform
может помочь сгенерировать массив range
, который значительно упрощает работу с подстроками:
Создание NSRange из диапазона до Swift 4
Если вы перешли в Xcode на версию 9, стандартная библиотека Swift для Swift 4 предоставляет метод прямого преобразования из Range<String.Index>
в NSRange
. Это определенно функция, которую с нетерпением ждут многие разработчики, потому что иногда приходится иметь дело с NSRange
, когда определенные вызовы функций еще не полностью перенесены на собственный Swift. Вот пример NSAttributedString
ниже:
Для более плавного перехода на текущую версию Swift мы можем реализовать грамматически совместимую функцию для создания NSRange
из Range
:
Тестовые функции выше на игровой площадке
По сути, приведенный выше код содержит элементы, которые нам нужны для поиска и возврата диапазонов всех вхождений данной строки. Давайте протестируем и посмотрим на результат в приведенном ниже фрагменте:
А на игровой площадке консоль журнала будет выглядеть так:
[Int] : [12, 31, 50, 69, 88]
`Range` : playground
`Range` : playground
`Range` : playground
`Range` : playground
`Range` : playground
`NSRange` : playground
`NSRange` : playground
`NSRange` : playground
`NSRange` : playground
`NSRange` : playground
Заключение
Спасибо за прочтение!