Як я можу використовувати підписки String slicing в Swift 4?


294

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


var str = "Привіт, майданчик" нехай indexcut = str.firstIndex (of: ",") print (String (str [.. <indexcut!])) print (String (str [indexcut! ...]))
користувач1828845

Відповіді:


375

Ви повинні залишити одну сторону порожньою , звідси і назва "частковий діапазон".

let newStr = str[..<index]

Те саме означає частковий діапазон від операторів, просто залиште іншу сторону порожньою:

let newStr = str[index...]

Майте на увазі, що ці оператори діапазону повертають a Substring. Якщо ви хочете перетворити його в рядок, використовуйте Stringфункцію ініціалізації:

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

Детальніше про нові підрядки ви можете прочитати тут .


8
str[..<index]повертає a Substring. Якщо ви хочете newStrбути асистенцією, Stringви повинні написати:let newStr = "\(str[..<index])"
Lindemann

12
Використовуючи інтерполяцію рядки з одинаком Substring, ймовірно , трохи заплутаним, так як то , що ви на самому справі намагаєтеся досягти є Stringініціалізація: let newStr = String(str[..<index]).
Гері

5
Оновлення коду , де моє значення «індекс» просто ціле дає повідомлення про помилку, Cannot subscript a value of type 'String' with an index of type 'PartialRangeUpTo<Int>'. Які типи значень повинні бути використані там?
ConfusionTowers

22
@ConfusionTowers, рядкові індекси Swift не є цілими числами , і це не змінилося з версією 4. Можливо, вам знадобиться str[..<str.index(str.startIndex, offsetBy: 8)]щось подібне. Майте на увазі, що str.indexце операція лінійного часу у функції offsetBy.
zneak

6
@zneak Ви, мабуть, хочетеstr.prefix(8)
Тім Вермеулен

264

Перетворити підрядку (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

5
Perfecto, і дякую, що надали 3 та 4 приклади поряд, полегшує оновлення мого проекту!
Етан Паркер

86

Швидкий 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)
  }
}

14
ця функціональність повинна бути швидкою поведінкою за замовчуванням.
Лаїміс

4
Однозначно PR це у Swift lib: D
OhadM

2
Це виправлення найпотворнішої частини Швидкого.
Дмитро

@Dmitry комусь не сподобалось, оскільки ця відповідь має -2. : D
dimpiax

Це погана відповідь, оскільки оператор індексів приховує складність O (n) функції індексу. Хороший API програмування використовує лише підпис для позначення швидкого пошуку.
ragnarius

38

Коротше в Swift 4/5:

var string = "123456"
string = String(string.prefix(3)) //"123"
string = String(string.suffix(3)) //"456"

26

Перетворення вашого коду в Swift 4 також можна здійснити таким чином:

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

Ви можете використовувати код нижче, щоб мати новий рядок:

let newString = String(str.prefix(upTo: index))

17

підряд (з: індекс) Перетворено на [індекс ...]

Перевірте зразок

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

text.substring(from: index) // "4567890"   [Swift 3]
String(text[index...])      // "4567890"   [Swift 4]

1
символи застаріли в Swift 4, я думаю, вам доведеться змінити приклад, щоб отримати індекс для Swift 4
AbuTaareq

Це мені допомогло. tnx
user1105951

17

Швидкий5

(Метод підрядки 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

2
Все ще працює в Swift 5. Я шукав підрядку в стилі Java ( fromдо to-1, наприклад, "Hello".substring(1,4)повертає "ell"). З невеликою модифікацією ( startIndex..<endIndex) це найкраще рішення, яке я знайшов до цих пір, і робить саме це лише кількома рядками коду.
Неф

9

Деякі корисні розширення:

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)
    }
}

Цікаво, я думав те саме. Чи рядок (рядок ["http: //" .endIndex ...]) чіткіший за устарену підрядку? line.substring (від: "http: //" .endIndex) можливо, поки вони не отримають заявлену мету дивовижної обробці рядків, вони не повинні зневажити підрядку.
possen

7

Приклад властивості uppercasedFirstCharacterзручності в Swift3 та Swift4.

Властивість uppercasedFirstCharacterNewдемонструє, як використовувати підрядник String slicing у 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"

1
Якщо ви маєте на увазі підрядку (з: діапазон) -> само [діапазон]
Арсен Вартбаронов,

6

Ви можете створити власний метод 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)
    }
}

Якщо це буде прийнято в endIndex, воно також має бути в змозі впоратися поза межами.
Джей

5

Створення 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

нехай префікс = str [... <index>] замість str [.. <index>] відсутня одна точка.
AbuTaareq

@AbuTaareq, про кого ти йдеш? нехай префікс = str [.. <індекс], він ідеальний. (рядок префікса). Спробуйте в ігровому майданчику, щоб отримати більше контексту.
Ашіс Лаха

4

Я написав розширення рядка для заміни "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: Факультативи змушені розгортати. Будь ласка, додайте перевірку безпеки типу, де це необхідно.


Застереження: необов’язкові змушені розгортати. при необхідності додайте перевірку безпеки.
byJeevan

3

При програмуванні у мене часто є рядки з просто простими A-Za-z і 0-9. Немає необхідності у складних діях Index. Це розширення базується на звичайних старих лівих / середніх / правих функціях.

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)
    }
}

Чудова ідея!! Сумно, хоча існує потреба в абстрактних функціях Swift лише тому, що вони постійно змінюють, як все працює. Здається, вони хочуть, щоб ми всі зосередились на конструкціях, а не на продуктивності. У будь-якому разі я зробив невеликі оновлення вашого тонкого коду: pastebin.com/ManWmNnW
Фредрік Йоханссон

2

за допомогою цього методу ви можете отримати певний діапазон string. вам потрібно пройти індекс запуску і після цього загальну кількість символів, які ви хочете.

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])
    }
}

2

Це моє рішення, без попередження, без помилок, але ідеально

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)])

Використання encodedOffsetє вважається шкідливим і буде застарілим .
Мартін Р

1

Сподіваюсь, це допоможе трохи більше: -

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)

0

Сподіваюся, це буде корисним.

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(","))

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

Можна спробувати таким чином і отримаєте належні результати.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.