Как я могу использовать подстроку String в Swift 4? 'substring (to :)' устарела: используйте подстрочный индекс среза с оператором 'частичный диапазон от'

У меня есть следующий простой код, написанный на Swift 3:

let str = "Hello, playground"
let index = str.index(of: ",")!
let newStr = str.substring(to: index)

Из Xcode 9 beta 5 я получаю следующее предупреждение:

"substring(to:)" устарело: используйте нижний индекс среза String с оператором "частичный диапазон от".

Как можно использовать этот индекс среза с частичным диапазоном от в Swift 4?


person Adrian    schedule 08.08.2017    source источник
comment
var str = Привет, площадка let indexcut = str.firstIndex (of:,) print (String (str [.. ‹indexcut!])) print (String (str [indexcut! ...]))   -  person user1828845    schedule 24.07.2019


Ответы (19)


Вы должны оставить одну сторону пустой, отсюда и название «частичный диапазон».

let newStr = str[..<index]

То же самое для операторов частичного диапазона из, просто оставьте другую сторону пустой:

let newStr = str[index...]

Имейте в виду, что эти операторы диапазона возвращают Substring. Если вы хотите преобразовать его в строку, используйте функцию инициализации String:

let newStr = String(str[..<index])

Подробнее о новых подстроках можно узнать здесь.

person Tamás Sengel    schedule 08.08.2017
comment
str[..<index] возвращает Substring. Если вы хотите, чтобы newStr был String, вы должны написать: let newStr = "\(str[..<index])" - person Lindemann; 21.08.2017
comment
Использование строковой интерполяции с одиночным Substring, вероятно, немного сбивает с толку, поскольку на самом деле вы пытаетесь выполнить String инициализацию: let newStr = String(str[..<index]). - person Gary; 31.08.2017
comment
При обновлении кода, в котором значение индекса было просто целым числом, появляется сообщение об ошибке Cannot subscript a value of type 'String' with an index of type 'PartialRangeUpTo<Int>'. Какие типы значений нужно там использовать? - person ConfusionTowers; 22.09.2017
comment
@ConfusionTowers, Строковые индексы Swift не являются целыми числами, и это не изменилось в версии 4. Возможно, вам понадобится str[..<str.index(str.startIndex, offsetBy: 8)] или что-то подобное. Имейте в виду, что str.index - это операция линейного времени в зависимости от offsetBy. - person zneak; 23.09.2017
comment
@zneak Ты, наверное, хочешь str.prefix(8) - person Tim Vermeulen; 24.09.2017
comment
Уродливый синтаксис. Ненавижу Swift за такие выражения: ?? !! a !! a? a a? [.. ‹index] [index ...] СУПЕР НЕЧИТАЕМЫЙ !!! - person Roman M; 16.12.2017
comment
Есть ли оператор для подстроки от индекса до конца, но без знака в индексе? str[index>..] не работает :( Или надо индекс смещать? - person ndreisg; 03.10.2018
comment
как создать индекс из int? - person Ammar Mujeeb; 24.12.2018
comment
Почему Swift так усложняет жизнь? Строковые манипуляции Python намного лучше str = "Hello Python" print(str[0:2]) результат: Он - person NamNamNam; 14.05.2019

Преобразование подстроки (Swift 3) в нарезку строки (Swift 4)

Примеры в Swift 3, 4:

let newStr = str.substring(to: index) // Swift 3
let newStr = String(str[..<index]) // Swift 4

let newStr = str.substring(from: index) // Swift 3
let newStr = String(str[index...]) // Swift 4 

let range = firstIndex..<secondIndex // If you have a range
let newStr = = str.substring(with: range) // Swift 3
let newStr = String(str[range])  // Swift 4
person Mohammad Sadegh Panadgoo    schedule 07.10.2017
comment
Perfecto, и спасибо за то, что привели 3 и 4 примера рядом, упрощает обновление моего проекта! - person Ethan Parker; 11.11.2017

Свифт 5, 4

использование

let text = "Hello world"
text[0] // H
text[...3] // "Hell"
text[6..<text.count] // world
text[NSRange(location: 6, length: 3)] // wor

Код

import Foundation

public extension String {
  subscript(value: Int) -> Character {
    self[index(at: value)]
  }
}

public extension String {
  subscript(value: NSRange) -> Substring {
    self[value.lowerBound..<value.upperBound]
  }
}

public extension String {
  subscript(value: CountableClosedRange<Int>) -> Substring {
    self[index(at: value.lowerBound)...index(at: value.upperBound)]
  }

  subscript(value: CountableRange<Int>) -> Substring {
    self[index(at: value.lowerBound)..<index(at: value.upperBound)]
  }

  subscript(value: PartialRangeUpTo<Int>) -> Substring {
    self[..<index(at: value.upperBound)]
  }

  subscript(value: PartialRangeThrough<Int>) -> Substring {
    self[...index(at: value.upperBound)]
  }

  subscript(value: PartialRangeFrom<Int>) -> Substring {
    self[index(at: value.lowerBound)...]
  }
}

private extension String {
  func index(at offset: Int) -> String.Index {
    index(startIndex, offsetBy: offset)
  }
}
person dimpiax    schedule 08.10.2017
comment
эта функция должна быть быстрым поведением по умолчанию. - person Laimis; 06.01.2018
comment
Определенно PR это в Swift lib: D - person OhadM; 30.01.2019
comment
Это исправление самой уродливой части Swift. - person Dmitry; 30.05.2019
comment
@Dmitry кому-то это не понравилось, так как в этом ответе -2. : D - person dimpiax; 01.06.2019
comment
Это плохой ответ, поскольку оператор индекса скрывает сложность O (n) индексной функции. Хороший программный API использует только нижний индекс для обозначения быстрого поиска. - person ragnarius; 26.01.2020
comment
@ragnarius - В этом отношении он не хуже базовой библиотеки - person Dave; 28.07.2020

Короче в Swift 4/5:

let string = "123456"
let firstThree = String(string.prefix(3)) //"123"
let lastThree = String(string.suffix(3)) //"456"
person ilnur    schedule 23.03.2018

Преобразование вашего кода в Swift 4 также можно выполнить следующим образом:

let str = "Hello, playground"
let index = str.index(of: ",")!
let substr = str.prefix(upTo: index)

Вы можете использовать приведенный ниже код, чтобы получить новую строку:

let newString = String(str.prefix(upTo: index))
person Thyerri Mezzari    schedule 20.09.2017

Swift5

(Метод подстроки Java):

extension String {
    func subString(from: Int, to: Int) -> String {
       let startIndex = self.index(self.startIndex, offsetBy: from)
       let endIndex = self.index(self.startIndex, offsetBy: to)
       return String(self[startIndex..<endIndex])
    }
}

Использование:

var str = "Hello, Nick Michaels"
print(str.subString(from:7,to:20))
// print Nick Michaels
person August Lin    schedule 24.08.2018
comment
Все еще работает в Swift 5. Я искал подстроку в стиле Java (от from до to-1, например, "Hello".substring(1,4) возвращает ell). С небольшой модификацией (startIndex..<endIndex) это лучшее решение, которое я нашел до сих пор, которое делает именно это с помощью всего нескольких строк кода. - person Neph; 13.06.2019
comment
Это хорошо работает и является самым простым решением из всех. Спасибо! - person vfxdev; 02.09.2020

подстрока (from: index) преобразована в [index ...]

Проверить образец

let text = "1234567890"
let index = text.index(text.startIndex, offsetBy: 3)

text.substring(from: index) // "4567890"   [Swift 3]
String(text[index...])      // "4567890"   [Swift 4]
person Den    schedule 28.09.2017
comment
символы устарели в Swift 4, я думаю, вам нужно изменить пример, чтобы получить индекс для Swift 4 - person AbuTaareq; 03.03.2018
comment
Это мне помогло. tnx - person user1105951; 28.06.2019

Некоторые полезные расширения:

extension String {
    func substring(from: Int, to: Int) -> String {
        let start = index(startIndex, offsetBy: from)
        let end = index(start, offsetBy: to - from)
        return String(self[start ..< end])
    }

    func substring(range: NSRange) -> String {
        return substring(from: range.lowerBound, to: range.upperBound)
    }
}
person Johannes    schedule 03.10.2017
comment
Интересно, я думал о том же. Является ли строка (строка [http: //. EndIndex ...]) более понятной, чем устаревшая подстрока? line.substring (from: http: //.endIndex) может быть, пока они не достигнут заявленной цели удивительной обработки строк, им не следует отказываться от подстроки. - person possen; 22.10.2017

Пример удобного свойства uppercasedFirstCharacter в Swift3 и Swift4.

Свойство uppercasedFirstCharacterNew демонстрирует, как использовать индекс среза строки в Swift4.

extension String {

   public var uppercasedFirstCharacterOld: String {
      if characters.count > 0 {
         let splitIndex = index(after: startIndex)
         let firstCharacter = substring(to: splitIndex).uppercased()
         let sentence = substring(from: splitIndex)
         return firstCharacter + sentence
      } else {
         return self
      }
   }

   public var uppercasedFirstCharacterNew: String {
      if characters.count > 0 {
         let splitIndex = index(after: startIndex)
         let firstCharacter = self[..<splitIndex].uppercased()
         let sentence = self[splitIndex...]
         return firstCharacter + sentence
      } else {
         return self
      }
   }
}

let lorem = "lorem".uppercasedFirstCharacterOld
print(lorem) // Prints "Lorem"

let ipsum = "ipsum".uppercasedFirstCharacterNew
print(ipsum) // Prints "Ipsum"
person Vlad    schedule 08.08.2017
comment
Если вы имеете в виду подстроку (with: range) - ›self [range] - person Arsen Vartbaronov; 18.09.2017

Вы можете создать свой собственный метод subString, используя расширение класса String, как показано ниже:

extension String {
    func subString(startIndex: Int, endIndex: Int) -> String {
        let end = (endIndex - self.count) + 1
        let indexStartOfText = self.index(self.startIndex, offsetBy: startIndex)
        let indexEndOfText = self.index(self.endIndex, offsetBy: end)
        let substring = self[indexStartOfText..<indexEndOfText]
        return String(substring)
    }
}
person Chhaileng    schedule 26.12.2017
comment
Если он будет принимать endIndex, он также должен иметь возможность обрабатывать выход за пределы. - person Jay; 03.05.2020

Создание SubString (префикс и суффикс) из String с использованием Swift 4:

let str : String = "ilike"
for i in 0...str.count {
    let index = str.index(str.startIndex, offsetBy: i) // String.Index
    let prefix = str[..<index] // String.SubSequence
    let suffix = str[index...] // String.SubSequence
    print("prefix \(prefix), suffix : \(suffix)")
}

Выход

prefix , suffix : ilike
prefix i, suffix : like
prefix il, suffix : ike
prefix ili, suffix : ke
prefix ilik, suffix : e
prefix ilike, suffix : 

Если вы хотите сгенерировать подстроку между двумя индексами, используйте:

let substring1 = string[startIndex...endIndex] // including endIndex
let subString2 = string[startIndex..<endIndex] // excluding endIndex
person Ashis Laha    schedule 08.12.2017
comment
let prefix = str [... ‹index›] вместо str [.. ‹index›] отсутствует одна точка. - person AbuTaareq; 03.03.2018
comment
@AbuTaareq, о каком вы говорите? пусть prefix = str [.. ‹index], отлично. (строка префикса). Попробуйте на игровой площадке, чтобы получить больше контекста. - person Ashis Laha; 04.03.2018

Я написал расширение строки для замены String: subString:

extension String {
    
    func sliceByCharacter(from: Character, to: Character) -> String? {
        let fromIndex = self.index(self.index(of: from)!, offsetBy: 1)
        let toIndex = self.index(self.index(of: to)!, offsetBy: -1)
        return String(self[fromIndex...toIndex])
    }
    
    func sliceByString(from:String, to:String) -> String? {
        //From - startIndex
        var range = self.range(of: from)
        let subString = String(self[range!.upperBound...])
        
        //To - endIndex
        range = subString.range(of: to)
        return String(subString[..<range!.lowerBound])
    }
    
}

Использование: "Date(1511508780012+0530)".sliceByString(from: "(", to: "+")

Пример результата: 1511508780012

PS: Optionals вынуждены разворачивать. При необходимости добавьте проверку безопасности типа.

person byJeevan    schedule 24.11.2017
comment
Внимание: необязательные параметры принудительно разворачиваются. при необходимости добавьте проверку безопасности типа. - person byJeevan; 24.03.2018

При программировании я часто использую строки с простыми буквами A-Za-z и 0-9. Нет необходимости в сложных действиях с индексом. Это расширение основано на простых старых функциях left / mid / right.

extension String {

    // LEFT
    // Returns the specified number of chars from the left of the string
    // let str = "Hello"
    // print(str.left(3))         // Hel
    func left(_ to: Int) -> String {
        return "\(self[..<self.index(startIndex, offsetBy: to)])"
    }

    // RIGHT
    // Returns the specified number of chars from the right of the string
    // let str = "Hello"
    // print(str.left(3))         // llo
    func right(_ from: Int) -> String {
        return "\(self[self.index(startIndex, offsetBy: self.length-from)...])"
    }

    // MID
    // Returns the specified number of chars from the startpoint of the string
    // let str = "Hello"
    // print(str.left(2,amount: 2))         // ll
    func mid(_ from: Int, amount: Int) -> String {
        let x = "\(self[self.index(startIndex, offsetBy: from)...])"
        return x.left(amount)
    }
}
person Vincent    schedule 13.10.2017
comment
Отличная идея!! Печально, однако, что есть необходимость абстрагироваться от Swift-функций только потому, что они постоянно меняют принцип работы. Думаю, они хотят, чтобы мы все сосредоточились на конструкциях, а не на производительности. В любом случае, я внес небольшие изменения в ваш прекрасный код: pastebin.com/ManWmNnW - person Fredrik Johansson; 22.11.2017

Надеюсь, это поможет немного больше: -

var string = "123456789"

Если вам нужна подстрока после определенного индекса.

var indexStart  =  string.index(after: string.startIndex )// you can use any index in place of startIndex
var strIndexStart   = String (string[indexStart...])//23456789

Если вам нужна подстрока после удаления некоторой строки в конце.

var indexEnd  =  string.index(before: string.endIndex)
var strIndexEnd   = String (string[..<indexEnd])//12345678

вы также можете создавать индексы с помощью следующего кода: -

var  indexWithOffset =  string.index(string.startIndex, offsetBy: 4)
person Anurag Bhakuni    schedule 15.02.2018

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

extension String{
    func substring(fromIndex : Int,count : Int) -> String{
        let startIndex = self.index(self.startIndex, offsetBy: fromIndex)
        let endIndex = self.index(self.startIndex, offsetBy: fromIndex + count)
        let range = startIndex..<endIndex
        return String(self[range])
    }
}
person jayesh kanzariya    schedule 24.05.2018

Это мое решение, без предупреждений, без ошибок, но идеально

let redStr: String = String(trimmStr[String.Index.init(encodedOffset: 0)..<String.Index.init(encodedOffset: 2)])
let greenStr: String = String(trimmStr[String.Index.init(encodedOffset: 3)..<String.Index.init(encodedOffset: 4)])
let blueStr: String = String(trimmStr[String.Index.init(encodedOffset: 5)..<String.Index.init(encodedOffset: 6)])
person Johnny    schedule 07.11.2017
comment
Использование encodedOffset считается вредным и будет быть устаревшим . - person Martin R; 21.03.2019

var str = "Hello, playground"
let indexcut = str.firstIndex(of: ",")
print(String(str[..<indexcut!]))
print(String(str[indexcut!...]))

Вы можете попробовать таким способом и получите должный результат.

person user1828845    schedule 24.07.2019

Если вы пытаетесь просто получить подстроку до определенного символа, вам не нужно сначала искать индекс, вы можете просто использовать метод prefix(while:)

let str = "Hello, playground"
let subString = str.prefix { $0 != "," } // "Hello" as a String.SubSequence
person Abizern    schedule 22.07.2021
comment
Спасибо! Я многому научился из этого. Если кому-то еще сложно понять синтаксис, он хорошо объяснен в docs.swift. org / swift-book / LanguageGuide / Closures.html Прочтите о выражениях замыкания и замыкающих замыканиях. - person Magnus; 27.07.2021

Надеюсь, это будет полезно.

extension String {
    func getSubString(_ char: Character) -> String {
        var subString = ""
        for eachChar in self {
            if eachChar == char {
                return subString
            } else {
                subString += String(eachChar)
            }
        }
        return subString
    }
}


let str: String = "Hello, playground"
print(str.getSubString(","))
person Anand Verma    schedule 31.05.2018