Я обновлял свой старый код и ответы с помощью Swift 3, но когда я перешел к Swift Strings и Indexing с подстроками, все стало запутанным.
Конкретно я пробовал следующее:
let str = "Hello, playground"
let prefixRange = str.startIndex..<str.startIndex.advancedBy(5)
let prefix = str.substringWithRange(prefixRange)
где вторая строка давала мне следующую ошибку
Значение типа 'String' не имеет члена substringWithRange
Я вижу, что String
теперь есть следующие методы:
str.substring(to: String.Index)
str.substring(from: String.Index)
str.substring(with: Range<String.Index>)
Сначала это действительно смущало меня, поэтому я начал играть с индексом и диапазоном . Это дополнительный вопрос и ответ для подстроки. Я добавляю ответ ниже, чтобы показать, как они используются.
Ответы:
Все следующие примеры использования
Swift 4
Строки получили довольно большой пересмотр в Swift 4. Когда вы получаете некоторую подстроку из String сейчас, вы получаете
Substring
тип назад, а не aString
. Почему это? Строки являются типами значений в Swift. Это означает, что если вы используете одну строку для создания новой, то она должна быть скопирована. Это хорошо для стабильности (никто не собирается менять это без вашего ведома), но плохо для эффективности.Подстрока, с другой стороны, является ссылкой на исходную строку, из которой она получена. Вот изображение из документации, иллюстрирующее это.
Копирование не требуется, поэтому его гораздо эффективнее использовать. Однако представьте, что вы получили Подстроку из десяти символов из Строки с миллионами символов. Поскольку Подстрока ссылается на Строку, системе придется удерживать всю Строку до тех пор, пока Подстрока находится рядом. Таким образом, всякий раз, когда вы закончите манипулировать своей подстрокой, преобразуйте ее в строку.
Это скопирует только подстроку, и память, содержащая старую строку, может быть восстановлена . Подстроки (как тип) должны быть недолговечными.
Еще одно большое улучшение в Swift 4 заключается в том, что Strings являются коллекциями (опять же). Это означает, что все, что вы можете сделать с коллекцией, вы можете сделать со строкой (использовать индексы, перебирать символы, фильтровать и т. Д.).
В следующих примерах показано, как получить подстроку в Swift.
Получение подстрок
Вы можете получить подстроку из строки с помощью индексов или ряд других методов (например,
prefix
,suffix
,split
). Вы все еще должны использовать,String.Index
а неInt
индекс для диапазона, хотя. (Смотрите мой другой ответ, если вам нужна помощь с этим.)Начало строки
Вы можете использовать нижний индекс (обратите внимание на односторонний диапазон Swift 4):
или
prefix
:или даже проще:
Конец строки
Используя подписки:
или
suffix
:или даже проще:
Обратите внимание, что при использовании
suffix(from: index)
мне пришлось отсчитывать от конца с помощью-10
. В этом нет необходимости, когда просто используетсяsuffix(x)
, который принимает последниеx
символы строки.Диапазон в строке
Опять же, мы просто используем подписки здесь.
преобразование
Substring
вString
Не забывайте, что, когда вы будете готовы сохранить свою подстроку, вам следует преобразовать ее в такую,
String
чтобы можно было очистить память старой строки.Используя
Int
расширение индекса?Я не решаюсь использовать
Int
расширение на основе индекса после прочтения статьи « Строки в Swift 3» от Airspeed Velocity и Оле Бегеманна. Хотя в Swift 4 строки являются коллекциями, команда Swift специально не использовалаInt
индексы. Это все ещеString.Index
. Это связано с тем, что символы Swift состоят из различного числа кодовых точек Unicode. Фактический индекс должен быть уникально рассчитан для каждой строки.Должен сказать, я надеюсь, что команда Swift найдет способ отвлечься
String.Index
в будущем. Но до них я выбираю использовать их API. Это помогает мне помнить, что манипуляции со строками - это не простоInt
поиск по индексу.источник
garbage collected
;-) Я надеюсь, что люди здесь знают, что в Swift нет сборки мусора.Я действительно разочарован в модели доступа Swift String: все должно быть
Index
. Все, что я хочу, - это получить доступ к i-му символу строки, используяInt
не корявый индекс и продвижение (что случается с каждым основным выпуском). Поэтому я сделал расширение дляString
:источник
let str = "🇨🇭🇩🇪🇺🇸Hello"
print(str.substring(to: 2))
str[5]
, я хочу получить доступ к символу с индексом 5, каким бы ни был этот символ или сколько байт для него требуется. Разве Swift не все о производительности разработчика?countElement(str)
для определения длины. В Swift 3 Apple сделала строку, не соответствующую,Sequence
и заставила всех использоватьstr.characters
вместо нее. Эти ребята не боятся вносить изменения. Их упрямство при целочисленной подписке действительно трудно понятьРасширение Swift 5:
Применение:
Или Юникод:
источник
count
был доступен толькоself.characters
CountableClosedRange<Int>
если вы хотите написать, напримерs[0...2]
.Свифт 4 и 5:
Как это использовать:
источник
Swift 4
В Swift 4
String
соответствуетCollection
. Вместо этогоsubstring
мы должны теперь использоватьsubscript.
Так что, если вы хотите вырезать только слово"play"
из"Hello, playground"
, вы можете сделать это следующим образом:Интересно знать, что это даст вам
Substring
вместоString
. Это быстро и эффективно, посколькуSubstring
разделяет хранилище с оригинальной строкой. Однако совместное использование памяти может также легко привести к утечкам памяти.Вот почему вы должны скопировать результат в новую строку, как только вы захотите очистить исходную строку. Вы можете сделать это используя обычный конструктор:
Вы можете найти больше информации о новом
Substring
классе в [документации Apple]. 1Итак, если вы, например, получите a
Range
как результатNSRegularExpression
, вы можете использовать следующее расширение:источник
text[Range( nsRange , in: text)!]
Вот функция, которая возвращает подстроку данной подстроки, когда предоставляются начальный и конечный индексы. Для полной справки вы можете посетить ссылки, приведенные ниже.
Вот ссылка на сообщение в блоге, которое я создал для работы со строками в Swift. Манипуляции со строками в Swift (также охватывает Swift 4)
Или вы можете увидеть эту суть на GitHub
источник
У меня была такая же начальная реакция. Я также был разочарован тем, как синтаксис и объекты так сильно меняются в каждом основном выпуске.
Тем не менее, по опыту я понял, что в конечном итоге я всегда страдаю от последствий борьбы с «переменами», например, от работы с многобайтовыми символами, что неизбежно, если вы смотрите на глобальную аудиторию.
Поэтому я решил признать и уважать усилия, прилагаемые инженерами Apple, и внести свой вклад, поняв их мышление, когда они придумали этот «ужасающий» подход.
Вместо создания расширений, которые являются просто обходным путем, чтобы сделать вашу жизнь проще (я не говорю, что они неправильные или дорогие), почему бы не выяснить, как Strings теперь разработаны для работы.
Например, у меня был этот код, который работал на Swift 2.2:
и после отказа от попыток заставить работать тот же подход, например, с использованием Substrings, я наконец-то понял концепцию обработки Strings как двунаправленной коллекции, для которой я получил эту версию того же кода:
Я надеюсь, что это способствует ...
источник
То же разочарование, это не должно быть так сложно ...
Я скомпилировал этот пример получения позиций для подстроки из текста большего размера:
return («почему», 0, 3) («подстроки», 26, 36) («Swift3», 40, 46)
источник
Я новичок в Swift 3, но, ища
String
аналогию (индекс) для аналогии, я думаю, что индекс похож на «указатель», ограниченный строкой, и Int может помочь как независимый объект. Используя синтаксис base + offset, мы можем получить i-й символ из строки с кодом ниже:Для диапазона символов (индексов) из строки с использованием синтаксиса String (range) мы можем получить от i-го до f-го символов с кодом ниже:
Для подстроки (диапазона) из строки, используя String.substring (диапазон), мы можем получить подстроку, используя код ниже:
Ноты:
I и F начинаются с 0.
Для f-го я использую offsetBY: f + 1, поскольку диапазон подписки используют .. <(полуоткрытый оператор), не включая f-ю позицию.
Конечно, должны включать в себя проверки ошибок, таких как неверный индекс.
источник
Свифт 4+
Возвращает подпоследовательность первых n символов или всю строку, если строка короче. (вдохновлено: https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.text/take.html )
Пример:
источник
Я довольно механическое мышление. Вот основы ...
Свифт 4 Свифт 5
Результатом является подстрока, означающая, что она является частью исходной строки. Чтобы получить полноценную отдельную строку, просто используйте, например,
Это то, что я использую:
источник
Swift 4
источник
Я создал простое расширение для этого (Swift 3)
источник
Вот более общая реализация:
Эта техника все еще используется
index
для соответствия стандартам Swift и подразумевает полный характер.Подстрока из 3-го символа:
Я использовал верблюда,
subString
чтобы указать, что он возвращает a,String
а не aSubstring
.источник
Основываясь на вышеизложенном, мне нужно было разбить строку на непечатаемый символ, удалив непечатный символ. Я разработал два метода:
который я собрал, используя некоторые ответы выше.
Поскольку String - это коллекция, я сделал следующее:
Который для меня был более интуитивным. Какой из них лучше? Я не могу сказать, что они оба работают со Swift 5
источник
Swift 4
«Подстрока» ( https://developer.apple.com/documentation/swift/substring ):
Пример расширения String:
Пример использования расширения String:
источник
Swift 5
let desiredIndex: Int = 7 let substring = str[String.Index(encodedOffset: desiredIndex)...]
Эта переменная подстроки даст вам результат.
Просто здесь Int конвертируется в индекс, а затем вы можете разделить строки. Если вы не получите ошибки.
источник