ฉันจะใช้สตริงตัวแบ่งการแบ่งใน 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 = "Hello, playground" ให้ indexcut = str.firstIndex (จาก: ",") พิมพ์ (String (str [.. <indexcut!]))) พิมพ์ (String (str [indexcut! ... ]))
user1828845

คำตอบ:


375

คุณควรเว้นว่างด้านใดด้านหนึ่งดังนั้นชื่อ "ช่วงบางส่วน"

let newStr = str[..<index]

ตัวย่อมาจากช่วงบางส่วนจากผู้ประกอบการเพียงแค่ปล่อยให้ด้านอื่น ๆ ที่ว่างเปล่า:

let newStr = str[index...]

Substringเก็บไว้ในใจว่าสิ่งเหล่านี้ผู้ประกอบการช่วงกลับ หากคุณต้องการแปลงเป็นสตริงให้ใช้Stringฟังก์ชันการกำหนดค่าเริ่มต้นของ:

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

คุณสามารถอ่านเพิ่มเติมเกี่ยวกับสตริงใหม่ที่นี่


8
str[..<index]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)
Tim Vermeulen

264

แปลง Substring (Swift 3) เป็น String Slicing (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 เคียงข้างกันทำให้การปรับปรุงโครงการของฉันง่ายขึ้น!
Ethan Parker

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
ฟังก์ชั่นนี้ควรเป็นพฤติกรรมการเริ่มต้นที่รวดเร็ว
Laimis

4
ประชาสัมพันธ์เรื่องนี้อย่างแน่นอนใน Swift lib: D
OhadM

2
นี่คือการแก้ไขส่วนที่น่าเกลียดที่สุดของ Swift
Dmitry

@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

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

2
ยังคงใช้งานได้ใน Swift 5 ฉันกำลังมองหาสตริงย่อยสไตล์ Java ( fromไปยังto-1, เช่น"Hello".substring(1,4)ส่งคืน "ell") ด้วยการดัดแปลงเล็ก ๆ ( startIndex..<endIndex) นี่เป็นทางออกที่ดีที่สุดที่ฉันเคยพบมาซึ่งจะทำอย่างนั้นด้วยรหัสเพียงไม่กี่บรรทัด
Neph

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

ที่น่าสนใจฉันก็คิดเหมือนกัน String (บรรทัด ["http: //" .endIndex ... ]) ชัดเจนกว่าสตริงย่อยที่คัดค้านหรือไม่ line.substring (จาก: "http: //" .endIndex) อาจจนกว่าพวกเขาจะได้รับเป้าหมายที่ระบุไว้ในการจัดการสตริงที่น่าทึ่งพวกเขาไม่ควรคัดค้านซับสตริง
อยู่

7

ตัวอย่างของ 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"

1
ถ้าคุณหมายถึงสตริงย่อย (ด้วย: ช่วง) -> ตัวเอง [ช่วง]
Arsen Vartbaronov

6

คุณสามารถสร้างวิธีการ subString ที่กำหนดเองโดยใช้ส่วนขยายของคลาสสตริงดังต่อไปนี้:

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 : 

หากคุณต้องการสร้างซับสตริงระหว่าง 2 ดัชนีให้ใช้:

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

ให้คำนำหน้า = str [... <index>] แทน str [.. <index>] จุดเดียวหายไป
AbuTaareq

@AbuTaareq คุณกำลังพูดถึงเรื่องอะไร ให้คำนำหน้า = str [.. <ดัชนี] มันสมบูรณ์แบบ (สตริงคำนำหน้า) ลองใช้พื้นที่เล่นเพื่อให้ได้บริบทมากขึ้น
Ashis Laha

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 ไม่จำเป็นต้องทำดัชนีที่ยาก ส่วนขยายนี้ขึ้นอยู่กับฟังก์ชั่นธรรมดาซ้าย / กลาง / ขวาเก่า

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
Fredrik Johansson

2

ด้วยวิธีนี้คุณจะได้รับช่วงของสตริงที่เฉพาะเจาะจงคุณต้องผ่านดัชนีเริ่มต้นและหลังจากจำนวนอักขระทั้งหมดที่คุณต้องการ

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จะถือว่าเป็นอันตรายและจะเลิก
Martin R

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

คุณสามารถลองด้วยวิธีนี้และจะได้รับผลลัพธ์ที่เหมาะสม

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.