Swift 4'te Dize alt dizesini nasıl kullanabilirim? 'substring (to :)' kullanımdan kaldırıldı: Lütfen 'kısmi aralık' işleciyle Dize dilimleme alt simge kullanın


294

Swift 3'te yazılmış aşağıdaki basit kod var:

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

Xcode 9 beta 5'ten aşağıdaki uyarıyı alıyorum:

' substring(to:)' kullanımdan kaldırıldı: Lütfen String'kısmi aralık' operatörüyle dilimleme alt simge kullanın .

Kısmi aralıklı bu dilimleme alt betiği Swift 4'te nasıl kullanılabilir?


var str = "Merhaba, oyun alanı" let indexcut = str.firstIndex (of: ",") print (String (str [.. <indexcut!])) print (String (str [indexcut! ...]))
user1828845

Yanıtlar:


375

Sen olmalıdır boş bir tarafını bırakın , dolayısıyla adını "kısmi aralığı".

let newStr = str[..<index]

Aynı şey operatörlerden kısmi menzil anlamına gelir , sadece diğer tarafı boş bırakın:

let newStr = str[index...]

Bu aralık işleçlerinin a Substring. Dizeye dönüştürmek istiyorsanız, Stringbaşlatma işlevini kullanın :

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

Yeni alt dizeler hakkında daha fazla bilgiyi buradan edinebilirsiniz .


8
str[..<index]döndürür a Substring. İsterseniz newStrbir olmak Stringsize yazma zorunda:let newStr = "\(str[..<index])"
Lindemann

12
Yalnız bir dize interpolasyon kullanarak Substringne gerçekten başarmak için çalışıyoruz çünkü muhtemelen biraz kafa karıştırıcı olduğunu Stringbaşlatma: let newStr = String(str[..<index]).
Gary

5
Kodumun 'index' değerinin bir tamsayı olduğu durumlarda güncellenmesi bir hata mesajı verir Cannot subscript a value of type 'String' with an index of type 'PartialRangeUpTo<Int>'. Orada ne tür değerler kullanılmalıdır?
ConfusionTowers

22
@ConfusionTowers, Swift dize indeksleri tamsayı değildir ve bu sürüm 4 ile değişmemiştir. Muhtemelen str[..<str.index(str.startIndex, offsetBy: 8)]böyle bir şeye ihtiyacınız olacaktır . Unutmayın str.indexbir olan doğrusal zamanlı fonksiyonu operasyon offsetBy.
zneak

6
@zneak Muhtemelen istiyorsunstr.prefix(8)
Tim Vermeulen

264

Alt Dizeyi (Swift 3) Dize Dilimlemeye Dönüştür (Swift 4)

Swift 3, 4'teki Örnekler:

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 ve 3 ve 4 örnekleri yan yana verdiğiniz için teşekkürler, projemin güncellenmesini kolaylaştırıyor!
Ethan Parker

86

Swift 5, 4

kullanım

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

kod

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
bu işlevsellik varsayılan hızlı davranış olmalıdır.
Laimis

4
Swift lib kesinlikle bu PR: D
OhadM

2
Bu Swift'in en çirkin kısmının bir düzeltmesidir.
Dmitry

@Dmitry birisinin hoşuna gitmedi, çünkü bu cevabın -2'si var. : D
dimpiax

Alt simge işleci, dizin işlevinin O (n) karmaşıklığını gizlediğinden bu kötü bir yanıttır. İyi bir programlama API'sı hızlı aramayı göstermek için yalnızca alt simge kullanır.
ragnarius

38

Swift 4/5 içinde daha kısa:

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

26

Kodunuzun Swift 4'e dönüştürülmesi de şu şekilde yapılabilir:

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

Yeni bir dizeye sahip olmak için aşağıdaki kodu kullanabilirsiniz:

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

18

Swift5

(Java'nın alt dize yöntemi):

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

Kullanımı:

var str = "Hello, Nick Michaels"
print(str.subString(from:7,to:20))
// print Nick Michaels

2
Yine Swift 5. çalışır I (Java tarzı alt dize arıyordu fromiçin to-1, örneğin "Hello".substring(1,4)"ell" iade). Küçük bir değişiklikle ( startIndex..<endIndex) bu şimdiye kadar bulduğum en iyi çözüm, sadece birkaç satırlık kodla bunu yapıyor.
Neph

17

substring (from: index) [index ...] biçimine dönüştürüldü

Örneği kontrol edin

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'te karakterler kullanımdan kaldırıldı, sanırım Swift 4
AbuTaareq

Bu bana yardımcı oldu. tnx
user1105951

9

Bazı yararlı uzantılar:

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

İlginç, ben de aynısını düşünüyordum. Dize (satır ["http: //" .endIndex ...]) kullanımdan kaldırılan alt dizeden daha mı açık? line.substring (from: "http: //" .endIndex) belki şaşırtıcı dize işleme belirtilen hedefini elde edene kadar, alt dizeyi reddetmemelidir.
possen

7

Örnek uppercasedFirstCharacterswift3 ve Swift4 içinde kolaylık özelliği.

Özellik uppercasedFirstCharacterNew, Swift4'te Dize dilimleme aboneliğinin nasıl kullanılacağını gösterir.

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
Eğer alt dize demek istiyorsanız (aralık: ile) -> kendini [aralık]
Arsen Vartbaronov

6

Özel subString yönteminizi, aşağıdaki gibi Class String uzantısını kullanarak oluşturabilirsiniz:

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

Eğer bu bir endIndex alacaksa, sınırların üstesinden gelebilmesi gerekir.
Jay

5

Swift 4 kullanarak Dize'den Alt Dizgi (önek ve sonek) oluşturma:

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

Çıktı

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

2 dizin arasında bir alt dize oluşturmak istiyorsanız, şunu kullanın:

let substring1 = string[startIndex...endIndex] // including endIndex
let subString2 = string[startIndex..<endIndex] // excluding endIndex

let öneki = str [... <index>] yerine str [.. <index>] tek nokta eksik.
AbuTaareq

@AbuTaareq, hangisinden bahsediyorsun? let öneki = str [.. <index], mükemmel. (önek dizesi). Daha fazla bağlam elde etmek için oyun alanında deneyin.
Ashis Laha

4

'String: subString:' yerine bir dize uzantısı yazdım

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

Kullanımı: "Date(1511508780012+0530)".sliceByString(from: "(", to: "+")

Örnek Sonuç : "1511508780012"

PS: Opsiyonelleri açmak zorunda. Lütfen gerekli olan yerlerde Tip güvenlik kontrolü ekleyin.


Dikkat: opsiyonel paketlerin açılması zorunludur. lütfen gerekirse Tip güvenlik kontrolü ekleyin.
Ocak 18

3

Programlama sırasında genellikle sadece düz A-Za-z ve 0-9 ile dizelerim var. Zor Dizin işlemlerine gerek yoktur. Bu uzantı düz eski sol / orta / sağ işlevlere dayanmaktadır.

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

İyi fikir!! Ne yazık ki Swift özelliklerinin soyutlanmasına ihtiyaç duyuluyor, çünkü işlerin nasıl çalıştığını sürekli değiştiriyorlar. Sanırım hepimiz verimlilik yerine yapılara odaklanmamızı istiyorlar. Her neyse, iyi kodunuzda bazı küçük güncellemeler yaptım: pastebin.com/ManWmNnW
Fredrik Johansson

2

Bu yöntemle belirli bir dizi dize alabilirsiniz. başlangıç ​​dizinini geçmeniz ve bundan sonra istediğiniz toplam karakter sayısını girmeniz gerekir.

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

Bu benim çözümüm, uyarı yok, hata yok, ama mükemmel

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

Kullanımı zararlıencodedOffset olarak kabul edilir ve kullanımdan kaldırılacaktır .
Martin R

1

Umarım bu biraz daha yardımcı olur: -

var string = "123456789"

Belirli bir dizinden sonra bir alt dize istiyorsanız.

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

Sonunda bazı dize kaldırdıktan sonra bir alt dize istiyorsanız.

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

ayrıca aşağıdaki kodla dizinler oluşturabilirsiniz: -

var  indexWithOffset =  string.index(string.startIndex, offsetBy: 4)

0

Umarım faydalı olur.

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

Bu şekilde deneyebilir ve uygun sonuçlar elde edersiniz.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.