Swift 4에서 문자열 슬라이싱 첨자를 어떻게 사용합니까?


294

Swift 3으로 작성된 다음과 같은 간단한 코드가 있습니다.

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

Xcode 9 베타 5에서 다음 경고가 표시됩니다.

' substring(to:)'는 사용되지 않습니다. String'partial range from'연산자와 함께 슬라이싱 아래 첨자를 사용하십시오 .

Swift 4 에서 부분 범위가 있는 이 슬라이싱 첨자를 어떻게 사용할 수 있습니까?


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

답변:


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])입니다.
Gary

5
내 'index'값이 정수인 코드를 업데이트하면 오류 메시지가 나타납니다 Cannot subscript a value of type 'String' with an index of type 'PartialRangeUpTo<Int>'. 어떤 유형의 값을 사용해야합니까?
ConfusionTowers

22
@ConfusionTowers, Swift 문자열 인덱스는 integer 가 아니며 버전 4에서는 변경되지 않았습니다. 아마도 필요할 str[..<str.index(str.startIndex, offsetBy: 8)]것입니다. 의 기능에 str.index대한 선형 시간 연산입니다 offsetBy.
zneak

6
@zneak 당신은 아마 원한다str.prefix(8)
Tim Vermeulen

264

하위 문자열 (Swift 3)을 문자열 슬라이싱 (Swift 4)으로 변환

스위프트 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
이것은 스위프트의 가장 추악한 부분의 수정입니다.
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
스위프트 4에서 사용되지 않는 문자는, 나는 당신이 스위프트 4 인덱스를 얻을 수있는 예제를 변경해야 할 생각
AbuTaareq

이것은 나를 도왔다. tnx
1105951

17

스위프트 5

(자바의 하위 문자열 방법) :

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
아직 스위프트 5. 작동 나는 (자바 스타일의 문자열을 찾고 있었어요 fromto-1, 예를 들어, "Hello".substring(1,4)"엘"반환). 작은 수정 ( 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 (line [ "http : //".endIndex ...])이 더 이상 사용되지 않는 하위 문자열보다 명확합니까? line.substring (from : "http : //".endIndex) 어쩌면 놀라운 문자열 처리라는 목표를 달성 할 때까지 하위 문자열을 더 이상 사용하지 않아야합니다.
possen

7

uppercasedFirstCharacterSwift3 및 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
> 자기 [범위] - : 당신은 (범위) 하위 문자열을 의미하는 경우
아르센 Vartbaronov

6

아래와 같이 String 클래스의 확장을 사용하여 사용자 정의 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를 받아들이려면 범위를 벗어날 수 있어야합니다.
Jay

5

Swift 4를 사용하여 String에서 SubString (접두사 및 접미사) 작성

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 [.. <index]로 설정하면 완벽합니다. (접두사 문자열). 더 많은 맥락을 얻으려면 운동장에서 시도하십시오.
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"

추신 : 선택 사항은 포장을 풀어야합니다. 필요한 경우 유형 안전 점검을 추가하십시오.


주의 : 옵션은 포장을 풀어야합니다. 필요한 경우 유형 안전 점검을 추가하십시오.
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)
    }
}

좋은 생각이야 !! 슬프게도 스위프트 기능을 추상화해야 할 필요가 있다는 것은 슬픈 일입니다. 일이 어떻게 작동하는지 끊임없이 변화하고 있기 때문입니다. 그들은 우리 모두가 생산성 대신 구조물에 집중하기를 원한다고 생각합니다. 어쨌든, 나는 당신의 좋은 코드에 약간의 업데이트를 만든 pastebin.com/ManWmNnW
프레드릭 요한슨

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.