Làm cách nào tôi có thể sử dụng các mục đăng ký String trong Swift 4?


294

Tôi có đoạn mã đơn giản sau được viết trong Swift 3:

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

Từ Xcode 9 beta 5, tôi nhận được cảnh báo sau:

' substring(to:)' Không được chấp nhận: Vui lòng sử dụng Stringcắt con với toán tử 'phạm vi một phần từ'.

Làm thế nào có thể đăng ký cắt lát với phạm vi một phần từ Swift 4?


var str = "Xin chào, sân chơi" hãy để indexcut = str.firstIndex (of: ",") print (String (str [.. <indexcut!])) print (String (str [indexcut! ...]))
người dùng1828845

Câu trả lời:


375

Bạn nên để trống một bên , do đó tên "một phần phạm vi".

let newStr = str[..<index]

Tương tự là viết tắt của một phần phạm vi từ các nhà khai thác, chỉ để trống phía bên kia:

let newStr = str[index...]

Hãy nhớ rằng các toán tử phạm vi trả về a Substring. Nếu bạn muốn chuyển đổi nó thành một chuỗi, hãy sử dụng Stringchức năng khởi tạo:

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

Bạn có thể đọc thêm về các chuỗi con mới ở đây .


8
str[..<index]trả về a Substring. Nếu bạn muốn newStrtrở thành một Stringbạn phải viết:let newStr = "\(str[..<index])"
Lindemann

12
Sử dụng phép nội suy chuỗi với một mình Substringcó lẽ hơi khó hiểu, vì những gì bạn đang thực sự cố gắng thực hiện là Stringkhởi tạo : let newStr = String(str[..<index]).
Gary

5
Cập nhật mã trong đó giá trị 'chỉ mục' của tôi chỉ đơn giản là một số nguyên mang lại thông báo lỗi , Cannot subscript a value of type 'String' with an index of type 'PartialRangeUpTo<Int>'. Những loại giá trị phải được sử dụng ở đó?
ConfusionTowers

22
@ConfusionTowers, các chỉ mục chuỗi Swift không phải là số nguyên và điều đó đã không thay đổi với phiên bản 4. Bạn có thể sẽ cần str[..<str.index(str.startIndex, offsetBy: 8)]hoặc một cái gì đó tương tự. Hãy nhớ rằng đó str.indexlà một hoạt động thời gian tuyến tính trong chức năng của offsetBy.
zneak

6
@zneak Có lẽ bạn muốnstr.prefix(8)
Tim Vermeulen

264

Chuyển đổi chuỗi con (Swift 3) sang cắt chuỗi (Swift 4)

Ví dụ trong 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, và cảm ơn vì đã đưa ra 3 và 4 ví dụ cạnh nhau, giúp việc cập nhật cách thức dự án của tôi dễ dàng hơn!
Ethan Parker

86

Swift 5, 4

Sử dụng

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
chức năng này phải là hành vi nhanh chóng mặc định.
Laimis

4
Chắc chắn PR này vào Swift lib: D
OhadM

2
Đây là bản sửa lỗi của phần xấu nhất của Swift.
Dmitry

@Dmitry ai đó không thích nó, vì câu trả lời này có -2. : D
dimpiax

Đây là một câu trả lời xấu vì toán tử đăng ký ẩn độ phức tạp O (n) của hàm chỉ mục. API lập trình tốt chỉ sử dụng đăng ký để biểu thị tra cứu nhanh.
ragnarius

38

Ngắn hơn trong Swift 4/5:

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

26

Việc chuyển đổi mã của bạn sang Swift 4 cũng có thể được thực hiện theo cách này:

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

Bạn có thể sử dụng mã dưới đây để có một chuỗi mới:

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

17

chuỗi con (từ: index) Được chuyển đổi thành [index ...]

Kiểm tra mẫu

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
các ký tự không được dùng nữa trong Swift 4, tôi nghĩ bạn phải thay đổi ví dụ để lấy chỉ mục cho Swift 4
AbuTaareq

Điều này đã giúp tôi. tnx
user1105951

17

Swift5

(Phương thức chuỗi con của 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])
    }
}

Sử dụng:

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

2
Vẫn hoạt động trong Swift 5. Tôi đang tìm kiếm một phong cách chuỗi Java ( fromđể to-1, ví dụ như "Hello".substring(1,4)lợi nhuận "ell"). Với một sửa đổi nhỏ ( startIndex..<endIndex) đây là giải pháp tốt nhất mà tôi đã tìm thấy cho đến nay, chính xác là chỉ với một vài dòng mã.
Cháu trai

9

Một số tiện ích mở rộng hữu ích:

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

Thú vị, tôi cũng nghĩ như vậy. Chuỗi (dòng ["http: //" .end Index ...]) có rõ ràng hơn chuỗi con không dùng nữa không? line.sub chuỗi (từ: "http: //" .end Index) có thể cho đến khi họ nhận được mục tiêu đã nêu là xử lý chuỗi tuyệt vời, họ không nên từ chối chuỗi con.
sở hữu

7

Ví dụ về uppercasedFirstCharactertài sản tiện lợi trong Swift3 và Swift4.

Thuộc tính uppercasedFirstCharacterNewthể hiện cách sử dụng đăng ký cắt lát Chuỗi trong 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
Nếu bạn có nghĩa là chuỗi con (với: phạm vi) -> tự [phạm vi]
Arsen Vartbaronov

6

Bạn có thể tạo phương thức SubString tùy chỉnh của mình bằng cách sử dụng phần mở rộng cho Chuỗi lớp như bên dưới:

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

Nếu điều này sẽ xảy ra trong một end Index, nó cũng cần có khả năng xử lý ngoài giới hạn.
Jay

5

Tạo SubString (tiền tố và hậu tố) từ Chuỗi bằng 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)")
}

Đầu ra

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

Nếu bạn muốn tạo một chuỗi con giữa 2 chỉ mục, hãy sử dụng:

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

hãy để tiền tố = str [... <index>] thay vì str [.. <index>] một dấu chấm đơn bị thiếu.
AbuTaareq ngày

@AbuTaareq, bạn đang nói về cái nào? hãy để tiền tố = str [.. <index], nó hoàn hảo. (chuỗi tiền tố). Hãy thử trong sân chơi để có thêm bối cảnh.
Ashis Laha

4

Tôi đã viết một phần mở rộng chuỗi để thay thế '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])
    }

}

Sử dụng : "Date(1511508780012+0530)".sliceByString(from: "(", to: "+")

Kết quả ví dụ : "1511508780012"

PS: Tùy chọn buộc phải mở khóa. Vui lòng thêm Kiểm tra an toàn Loại bất cứ khi nào cần thiết.


Chú ý: tùy chọn buộc phải mở khóa. vui lòng thêm Loại kiểm tra an toàn nếu cần thiết.
byJeevan

3

Khi lập trình tôi thường có các chuỗi chỉ đơn giản là A-Za-z và 0-9. Không cần các hành động Index khó khăn. Phần mở rộng này dựa trên các chức năng trái / giữa / phải cũ đơn giản.

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

Ý tưởng tuyệt vời!! Đáng buồn là mặc dù cần phải trừu tượng hóa các tính năng của Swift chỉ vì chúng liên tục thay đổi cách mọi thứ hoạt động. Đoán rằng họ muốn tất cả chúng ta tập trung vào các công trình thay vì năng suất. Dù sao, tôi đã thực hiện một số cập nhật nhỏ cho mã tốt của bạn: pastebin.com/ManWmNnW
Fredrik Johansson

2

với phương thức này, bạn có thể nhận được phạm vi chuỗi cụ thể. Bạn cần vượt qua chỉ mục bắt đầu và sau tổng số ký tự bạn muốn.

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

Đây là giải pháp của tôi, không cảnh báo, không có lỗi, nhưng hoàn hảo

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

Việc sử dụng encodedOffsetđược coi là có hại và sẽ không được chấp nhận .
Martin R

1

Hy vọng điều này sẽ giúp ít hơn:

var string = "123456789"

Nếu bạn muốn một chuỗi con sau một số chỉ mục cụ thể.

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

Nếu bạn muốn một chuỗi con sau khi loại bỏ một số chuỗi ở cuối.

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

bạn cũng có thể tạo các chỉ mục với mã sau: -

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

0

Hy vọng nó sẽ hữu ích.

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

Bạn có thể thử theo cách này và sẽ nhận được kết quả thích hợp.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.