Swift에서 문자열 하위 문자열은 어떻게 작동합니까


354

Swift 3으로 이전 코드와 답변을 업데이트했지만 Swift Strings 및 Indexing to substrings를 사용하면 혼란스러워졌습니다.

특히 나는 다음을 시도했다.

let str = "Hello, playground"
let prefixRange = str.startIndex..<str.startIndex.advancedBy(5)
let prefix = str.substringWithRange(prefixRange)

두 번째 줄에서 다음과 같은 오류가 발생했습니다.

'String'유형의 값에 'substringWithRange'멤버가 없습니다.

그 볼 String이제 다음과 같은 방법이 있나요 :

str.substring(to: String.Index)
str.substring(from: String.Index)
str.substring(with: Range<String.Index>)

이것들은 처음에 정말 혼란 스러웠으므로 색인과 범위를 다루기 시작했습니다 . 이것은 하위 문자열에 대한 후속 질문과 답변입니다. 사용 방법을 보여주기 위해 아래에 답변을 추가하고 있습니다.


2
문자열에서 부분 문자열을 가져
오려는

또는 아래 첨자 문자열 또는 하위 문자열 stackoverflow.com/questions/24092884/…
Leo Dabus

답변:


831

여기에 이미지 설명을 입력하십시오

다음 예제는 모두

var str = "Hello, playground"

스위프트 4

문자열은 Swift 4에서 상당히 큰 점검을 받았습니다. 이제 문자열에서 하위 문자열을 가져 오면 Substring 대신 유형이 반환 String됩니다. 왜 이런거야? 문자열은 Swift의 값 유형입니다. 즉, 하나의 문자열을 사용하여 새 문자열을 만들면 복사해야합니다. 이것은 안정성에는 좋지만 (다른 사람은 모르게 변경하지 않을 것임) 효율성에는 좋지 않습니다.

반면에 하위 문자열은 원래 문자열에 대한 참조입니다. 다음은이를 설명하는 문서 의 이미지 입니다.

복사가 필요하지 않으므로 사용하기가 훨씬 효율적입니다. 그러나 백만 개의 문자열에서 10 개의 문자 하위 문자열이 있다고 가정하십시오. 하위 문자열이 문자열을 참조하므로 시스템은 하위 문자열이있는 한 전체 문자열을 유지해야합니다. 따라서 부분 문자열을 다룰 때마다 문자열로 변환하십시오.

let myString = String(mySubstring)

이것은 부분 문자열만을 복사하고 오래된 문자열을 보유한 메모리를 회수 할 수 있습니다 . 하위 문자열 (유형)은 수명이 짧아야합니다.

Swift 4의 또 다른 큰 개선점은 Strings is Collections (다시)입니다. 즉, Collection에 대해 할 수있는 모든 작업을 String에 수행 할 수 있습니다 (아래 첨자 사용, 문자 반복, 필터 등).

다음 예제는 Swift에서 하위 문자열을 얻는 방법을 보여줍니다.

부분 문자열 얻기

첨자 나 여러 가지 다른 방법 (예 prefix: suffix, split) 을 사용하여 문자열에서 부분 문자열을 가져올 수 있습니다 . 그래도 범위에 String.Index대한 Int색인이 아닌 사용해야 합니다. ( 나의 다른 대답을보십시오 도움이 필요하면 .)

문자열의 시작

아래 첨자를 사용할 수 있습니다 (Swift 4 단면 범위 참고).

let index = str.index(str.startIndex, offsetBy: 5)
let mySubstring = str[..<index] // Hello

또는 prefix:

let index = str.index(str.startIndex, offsetBy: 5)
let mySubstring = str.prefix(upTo: index) // Hello

또는 더 쉬운 :

let mySubstring = str.prefix(5) // Hello

문자열의 끝

아래 첨자 사용 :

let index = str.index(str.endIndex, offsetBy: -10)
let mySubstring = str[index...] // playground

또는 suffix:

let index = str.index(str.endIndex, offsetBy: -10)
let mySubstring = str.suffix(from: index) // playground

또는 더 쉬운 :

let mySubstring = str.suffix(10) // playground

를 사용할 때 나는를 사용 suffix(from: index)하여 끝에서 다시 카운트해야 한다는 것을 유의하십시오 -10. String suffix(x)의 마지막 x문자를 취하는을 사용할 때 필요하지 않습니다 .

문자열의 범위

다시 우리는 단순히 아래 첨자를 사용합니다.

let start = str.index(str.startIndex, offsetBy: 7)
let end = str.index(str.endIndex, offsetBy: -6)
let range = start..<end

let mySubstring = str[range]  // play

변환 SubstringString

하위 문자열을 저장할 준비 String가되면 이전 문자열의 메모리를 정리할 수 있도록 하위 문자열을 변환해야 합니다.

let myString = String(mySubstring)

사용하여 Int인덱스 확장을?

Airspeed Velocity와 Ole Begemann의 Swift 3의 StringsInt 기사를 읽은 후 기본 색인 확장 을 사용하는 것이 주저합니다 . Swift 4에서는 Strings가 컬렉션이지만 Swift 팀은 의도적으로 인덱스를 사용하지 않았습니다 . 아직 입니다. 이것은 다양한 수의 유니 코드 코드 포인트로 구성된 스위프트 문자와 관련이 있습니다. 실제 인덱스는 모든 문자열에 대해 고유하게 계산되어야합니다.IntString.Index

나는 스위프트 팀이 String.Index미래 에 추상화 할 수있는 방법을 찾길 바란다 . 그러나 그들까지 API를 사용하기로 결정했습니다. 문자열 조작은 단순한 Int인덱스 조회 가 아니라는 것을 기억하는 데 도움이됩니다 .


9
삭제를위한 Thx. 제대로 된 요금. 애플은 이것을 너무 복잡하게 만들었다. 부분 문자열은 string.substring [from ... to]처럼 쉬워야합니다.
Teddy

정말 좋은 설명입니다. 하나의 작은 것을 제외하고 garbage collected;-) 나는 여기 사람들이 Swift에 가비지 수집이 없다는 것을 알기를 바랍니다.
Christian Anchor Dampf

@ChristianAnchorDampf, 의견을 보내 주셔서 감사합니다. 쓰레기 수거했습니다. 새로운 표현은 어떻습니까?
Suragch

얼마나 놀라운 답변입니까!
davidev

194

Swift의 String 액세스 모델에 정말 실망했습니다. 모든 것이이어야합니다 Index. 내가 원하는 것은 Int서투른 색인과 전진이 아닌을 사용하여 문자열의 i 번째 문자에 액세스하는 것입니다 (모든 주요 릴리스마다 변경됨). 그래서 나는 확장했다 String:

extension String {
    func index(from: Int) -> Index {
        return self.index(startIndex, offsetBy: from)
    }

    func substring(from: Int) -> String {
        let fromIndex = index(from: from)
        return String(self[fromIndex...])
    }

    func substring(to: Int) -> String {
        let toIndex = index(from: to)
        return String(self[..<toIndex])
    }

    func substring(with r: Range<Int>) -> String {
        let startIndex = index(from: r.lowerBound)
        let endIndex = index(from: r.upperBound)
        return String(self[startIndex..<endIndex])
    }
}

let str = "Hello, playground"
print(str.substring(from: 7))         // playground
print(str.substring(to: 5))           // Hello
print(str.substring(with: 7..<11))    // play

5
문자 는 1 바이트 이상일 수 있으므로 인덱스는 매우 유용합니다 . 시도let str = "🇨🇭🇩🇪🇺🇸Hello" print(str.substring(to: 2))
vadian

110
예, 문자 (예 : 확장 grapheme cluster )는 여러 바이트를 취할 수 있음을 이해합니다 . 내 좌절감은 자세한 색인 향상 방법을 사용하여 문자열의 문자에 액세스 해야하는 이유입니다. Swift 팀이 코어 라이브러리에 과부하를 추가하여 추상화하지 못하는 이유는 무엇입니까? 을 입력하면 str[5]인덱스 5에서 문자에 액세스하거나 해당 바이트 수에 관계없이 문자에 액세스하려고합니다. 스위프트가 개발자의 생산성에 관한 것이 아닙니까?
코드 다른

6
@RenniePet 애플이 문제를 인식하고 변화가 다가오고 있다고 생각합니다. GitHub의 Swift Evolution 페이지에 따르면 "Swift 4는 기본적으로 유니 코드 정확성을 유지하면서 문자열을보다 강력하고 사용하기 쉽게 만듭니다." 모호하지만 희망을 유지합시다
Code Different

3
@CodeDifferent 왜 애플이 첨자 문자 액세스를 추가하지 않았습니까? 사람들은 그것이 나쁜 일이라는 것을 이해하도록. 기본적으로 이중 루프 인 첨자를 사용하여 0..string.count에서 i를 수행하는 경우 두 번째 문자가 문자열의 각 바이트를 통과하여 다음 문자인지 확인해야합니다. index를 사용하여 반복하면 문자열을 한 번만 반복합니다. Btw, 이것을 스스로 싫어하지만 그것이 첨자 문자열을 신속하게 사용할 수없는 이유입니다.
Raimundas Sakalauskas

4
@RaimundasSakalauskas 그 주장은 나에게 날지 않습니다. C #에는 유니 코드 정확성과 정수 첨자가 모두있어 매우 편리합니다. Swift 1에서 Apple은 개발자가 countElement(str)길이를 찾기 위해 사용 하기를 원했습니다 . Swift 3에서 Apple은 문자열을 따르지 않고 Sequence모든 사람이 str.characters대신 사용하도록 강요 했습니다. 이 사람들은 변화를 두려워하지 않습니다. 이해하기 어려운 정수 첨자에 대한 그들의 고집
Code Different

102

스위프트 5 확장 :

extension String {
    subscript(_ range: CountableRange<Int>) -> String {
        let start = index(startIndex, offsetBy: max(0, range.lowerBound))
        let end = index(start, offsetBy: min(self.count - range.lowerBound, 
                                             range.upperBound - range.lowerBound))
        return String(self[start..<end])
    }

    subscript(_ range: CountablePartialRangeFrom<Int>) -> String {
        let start = index(startIndex, offsetBy: max(0, range.lowerBound))
         return String(self[start...])
    }
}

용법:

let s = "hello"
s[0..<3] // "hel"
s[3...]  // "lo"

또는 유니 코드 :

let s = "😎🤣😋"
s[0..<1] // "😎"

2
이 확장 프로그램을 게시 해 주셔서 감사합니다. 파이썬에서 왔을 때 스위프트는 익숙해지기보다 훨씬 어렵습니다. Objective C에서 Swift로 다른 방향으로 가고있는 사람들에게는 더 긍정적 인 확인이있는 것 같습니다.
user3064009

1
@Leon 방금 제거했습니다. 4.1 이전 count에 만 가능self.characters
Lou Zell

1
이 특정 확장으로주의해야 할 점이 있습니까? 애플이 왜 이런 짓을하지 않았습니까?
Andz

1
@Andz는 매우 비효율적입니다. 문자열의 시작 부분부터 두 번 시작하여 거기에서 모든 문자를 "범위"로 두 번 구문 분석해야합니다.
kareman

3
예를 들어 쓰고 싶다면 확장 프로그램CountableClosedRange<Int> 을 추가해야합니다 s[0...2].
Chris Frederick

24

스위프트 4 & 5 :

extension String {
  subscript(_ i: Int) -> String {
    let idx1 = index(startIndex, offsetBy: i)
    let idx2 = index(idx1, offsetBy: 1)
    return String(self[idx1..<idx2])
  }

  subscript (r: Range<Int>) -> String {
    let start = index(startIndex, offsetBy: r.lowerBound)
    let end = index(startIndex, offsetBy: r.upperBound)
    return String(self[start ..< end])
  }

  subscript (r: CountableClosedRange<Int>) -> String {
    let startIndex =  self.index(self.startIndex, offsetBy: r.lowerBound)
    let endIndex = self.index(startIndex, offsetBy: r.upperBound - r.lowerBound)
    return String(self[startIndex...endIndex])
  }
}

사용 방법:

"abcde"[0]-> "a"

"abcde"[0 ... 2]-> "abc"

"abcde"[2 .. <4]-> "cd"


20

스위프트 4

신속한 4에서 String준수합니다 Collection. 대신에 substring, 우리는 지금 사용해야 subscript.만 단어를 잘라 싶다면을 "play"에서 "Hello, playground"이 같은 그것을 할 수 :

var str = "Hello, playground"
let start = str.index(str.startIndex, offsetBy: 7)
let end = str.index(str.endIndex, offsetBy: -6)
let result = str[start..<end] // The result is of type Substring

알고 있으면 흥미 롭습니다 . Substring대신 String. Substring원래 문자열과 스토리지를 공유하므로 빠르고 효율적 입니다. 그러나이 방법으로 메모리를 공유하면 메모리 누수가 쉽게 발생할 수 있습니다.

그렇기 때문에 원래 문자열을 정리하려면 결과를 새 문자열로 복사해야합니다. 일반 생성자를 사용하여이 작업을 수행 할 수 있습니다.

let newString = String(result)

새로운 Substring클래스에 대한 자세한 정보 는 [Apple documentation]에서 찾을 수 있습니다 . 1

예를 들어 Range의 결과로 a를 얻는 NSRegularExpression경우 다음 확장을 사용할 수 있습니다.

extension String {

    subscript(_ range: NSRange) -> String {
        let start = self.index(self.startIndex, offsetBy: range.lowerBound)
        let end = self.index(self.startIndex, offsetBy: range.upperBound)
        let subString = self[start..<end]
        return String(subString)
    }

}

range.upperBound가> 문자열 길이 인 경우 코드가 중단됩니다. 또한 Swift의 첨자에 익숙하지 않기 때문에 샘플 사용법도 도움이되었습니다. datePartOnly = "2018-01-04-08 : 00"[NSMakeRange (0, 10)]와 같은 것을 포함 할 수 있습니다. 그외에, 아주 좋은 대답, +1 :).
dcp

요즘 그것은이 이상한 일이다 : text[Range( nsRange , in: text)!]
Fattie

10

다음은 시작 및 끝 인덱스가 제공 될 때 주어진 부분 문자열의 부분 문자열을 반환하는 함수입니다. 자세한 내용은 아래 링크를 참조하십시오.

func substring(string: String, fromIndex: Int, toIndex: Int) -> String? {
    if fromIndex < toIndex && toIndex < string.count /*use string.characters.count for swift3*/{
        let startIndex = string.index(string.startIndex, offsetBy: fromIndex)
        let endIndex = string.index(string.startIndex, offsetBy: toIndex)
        return String(string[startIndex..<endIndex])
    }else{
        return nil
    }
}

다음은 문자열 조작을 신속하게 처리하기 위해 만든 블로그 게시물에 대한 링크입니다. 스위프트에서의 문자열 조작 (Covers swift 4도)

또는 github 에서이 요점을 볼 수 있습니다


9

나는 같은 초기 반응을 보였습니다. 나도 모든 주요 릴리스에서 구문과 객체가 어떻게 급격하게 변하는 지에 대해 좌절했다.

그러나 전 세계 잠재 고객을보고 있다면 불가피한 멀티 바이트 문자를 다루는 것처럼 "변화"에 맞서 싸우는 결과를 항상 겪는 결과를 경험에서 깨달았습니다.

그래서 저는 Apple 엔지니어들이 겪은 노력을 인정하고 존중하기로 결정했고,이 "끔찍한"접근 방식을 떠 올렸을 때 그들의 사고 방식을 이해함으로써 저의 역할을 수행하기로 결정했습니다.

인생을 더 쉽게 만들기위한 해결 방법 인 확장 기능을 만드는 대신 (문자열이 잘못되었거나 비싸다고 말하지는 않습니다) 이제 문자열이 어떻게 작동하도록 설계되어 있는지 알아 내십시오.

예를 들어 Swift 2.2에서 작동하는이 코드가 있습니다.

let rString = cString.substringToIndex(2)
let gString = (cString.substringFromIndex(2) as NSString).substringToIndex(2)
let bString = (cString.substringFromIndex(4) as NSString).substringToIndex(2)

그리고 하위 문자열을 사용하여 동일한 접근 방식을 사용하려고 노력한 것을 포기한 후에 마침내 문자열을 양방향 컬렉션으로 취급하는 개념을 이해했습니다.이 코드는이 버전의 동일한 코드로 끝났습니다.

let rString = String(cString.characters.prefix(2))
cString = String(cString.characters.dropFirst(2))
let gString = String(cString.characters.prefix(2))
cString = String(cString.characters.dropFirst(2))
let bString = String(cString.characters.prefix(2))

이것이 도움이되기를 바랍니다 ...


1
복잡한 문제를 처리한다고해서 솔루션이 우아하다는 의미는 아닙니다. 다시 말하지만, 나는 또한 문제를 이해하지만 전체 String 클래스와 그것을 처리하는 것은 끔찍합니다.
inexcitus

5

같은 좌절감, 그렇게 어렵지 않아야합니다 ...

더 큰 텍스트에서 부분 문자열의 위치를 ​​얻는 다음 예제를 컴파일했습니다.

//
// Play with finding substrings returning an array of the non-unique words and positions in text
//
//

import UIKit

let Bigstring = "Why is it so hard to find substrings in Swift3"
let searchStrs : Array<String>? = ["Why", "substrings", "Swift3"]

FindSubString(inputStr: Bigstring, subStrings: searchStrs)


func FindSubString(inputStr : String, subStrings: Array<String>?) ->    Array<(String, Int, Int)> {
    var resultArray : Array<(String, Int, Int)> = []
    for i: Int in 0...(subStrings?.count)!-1 {
        if inputStr.contains((subStrings?[i])!) {
            let range: Range<String.Index> = inputStr.range(of: subStrings![i])!
            let lPos = inputStr.distance(from: inputStr.startIndex, to: range.lowerBound)
            let uPos = inputStr.distance(from: inputStr.startIndex, to: range.upperBound)
            let element = ((subStrings?[i])! as String, lPos, uPos)
            resultArray.append(element)
        }
    }
    for words in resultArray {
        print(words)
    }
    return resultArray
}

( "Why", 0, 3) ( "substrings", 26, 36) ( "Swift3", 40, 46)을 반환합니다.


3
이것은 일부 코드이지만 문자열 인덱싱 및 하위 문자열이 swift3에서 작동하는 방식을 실제로 설명하지는 않습니다.
Robert

5

Swift 3의 새로운 기능이지만 String유추를 위해 (인덱스) 구문을 살펴보면 인덱스는 문자열에 제한 된 "포인터"와 같으며 Int는 독립 객체로 도움이 될 수 있다고 생각합니다. base + offset 구문을 사용하면 다음 코드를 사용하여 문자열에서 i 번째 문자를 얻을 수 있습니다.

let s = "abcdefghi"
let i = 2
print (s[s.index(s.startIndex, offsetBy:i)])
// print c

문자열 (범위) 구문을 사용하는 문자열의 문자 범위 (인덱스)의 경우 다음 코드를 사용하여 i 번째 문자부터 f 번째 문자까지 얻을 수 있습니다.

let f = 6
print (s[s.index(s.startIndex, offsetBy:i )..<s.index(s.startIndex, offsetBy:f+1 )])
//print cdefg

String.substring (range)을 사용하여 문자열의 하위 문자열 (범위)의 경우 다음 코드를 사용하여 하위 문자열을 얻을 수 있습니다.

print (s.substring (with:s.index(s.startIndex, offsetBy:i )..<s.index(s.startIndex, offsetBy:f+1 ) ) )
//print cdefg

노트:

  1. i 번째와 f 번째는 0으로 시작합니다.

  2. f 번째로, offsetBY : f + 1을 사용합니다. 서브 스크립 션의 범위는 .. <(반 개방 연산자)를 사용하고 f 번째 위치는 포함하지 않기 때문입니다.

  3. 물론 유효하지 않은 인덱스와 같은 유효성 검사 오류를 포함해야합니다.


5

스위프트 4+

extension String {
    func take(_ n: Int) -> String {
        guard n >= 0 else {
            fatalError("n should never negative")
        }
        let index = self.index(self.startIndex, offsetBy: min(n, self.count))
        return String(self[..<index])
    }
}

처음 n 자의 하위 시퀀스 또는 문자열이 더 짧은 경우 전체 문자열을 반환합니다. (영감 : https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.text/take.html )

예:

let text = "Hello, World!"
let substring = text.take(5) //Hello

4

나는 기계적인 사고입니다. 기본 사항은 다음과 같습니다.

스위프트 4 스위프트 5

  let t = "abracadabra"

  let start1 = t.index(t.startIndex, offsetBy:0)
  let   end1 = t.index(t.endIndex, offsetBy:-5)
  let start2 = t.index(t.endIndex, offsetBy:-5)
  let   end2 = t.index(t.endIndex, offsetBy:0)

  let t2 = t[start1 ..< end1]
  let t3 = t[start2 ..< end2]                

  //or a shorter form 

  let t4 = t[..<end1]
  let t5 = t[start2...]

  print("\(t2) \(t3) \(t)")
  print("\(t4) \(t5) \(t)")

  // result:
  // abraca dabra abracadabra

결과는 하위 문자열이며 이는 원래 문자열의 일부임을 의미합니다. 완전히 분리 된 별도의 문자열을 얻으려면 예를 들어

    String(t3)
    String(t4)

이것이 내가 사용하는 것입니다 :

    let mid = t.index(t.endIndex, offsetBy:-5)
    let firstHalf = t[..<mid]
    let secondHalf = t[mid...]

3

스위프트 4

extension String {
    subscript(_ i: Int) -> String {
        let idx1 = index(startIndex, offsetBy: i)
        let idx2 = index(idx1, offsetBy: 1)
        return String(self[idx1..<idx2])
    }
}

let s = "hello"

s[0]    // h
s[1]    // e
s[2]    // l
s[3]    // l
s[4]    // o

2

이것을 위해 간단한 확장을 만들었습니다 (Swift 3)

extension String {
    func substring(location: Int, length: Int) -> String? {
        guard characters.count >= location + length else { return nil }
        let start = index(startIndex, offsetBy: location)
        let end = index(startIndex, offsetBy: location + length)
        return substring(with: start..<end)
    }
}

2

보다 일반적인 구현은 다음과 같습니다.

이 기술은 여전히 indexSwift의 표준을 준수하는 데 사용되며 완전한 특성을 의미합니다.

extension String
{
    func subString <R> (_ range: R) -> String? where R : RangeExpression, String.Index == R.Bound
    {
        return String(self[range])
    }

    func index(at: Int) -> Index
    {
        return self.index(self.startIndex, offsetBy: at)
    }
}

세 번째 문자에서 문자열을 하위로 나누려면 :

let item = "Fred looks funny"
item.subString(item.index(at: 2)...) // "ed looks funny"

낙타 subString를 사용 하여 a String가 아니라 a를 반환 함을 나타 냈습니다 Substring.


2

위의 내용을 바탕으로 인쇄하지 않는 문자를 삭제하여 인쇄하지 않는 문자로 문자열을 분할해야했습니다. 두 가지 방법을 개발했습니다.

var str = "abc\u{1A}12345sdf"
let range1: Range<String.Index> = str.range(of: "\u{1A}")!
let index1: Int = str.distance(from: str.startIndex, to: range1.lowerBound)
let start = str.index(str.startIndex, offsetBy: index1)
let end = str.index(str.endIndex, offsetBy: -0)
let result = str[start..<end] // The result is of type Substring
let firstStr = str[str.startIndex..<range1.lowerBound]

위의 답변 중 일부를 사용하여 정리했습니다.

String은 컬렉션이므로 다음을 수행했습니다.

var fString = String()
for (n,c) in str.enumerated(){

*if c == "\u{1A}" {
    print(fString);
    let lString = str.dropFirst(n + 1)
    print(lString)
    break
   }
 fString += String(c)
}*

나를 위해 어느 것이 더 직관적이었습니다. 어느 것이 가장 좋습니까? 둘 다 스위프트 5와 함께 작동한다고 말할 방법이 없습니다.


답변 주셔서 감사합니다. Swift 5의 문자열과 다른 점이 있습니까? 나는 아직 그것을 가지고 놀 시간이 없었습니다.
Suragch

그들은 그렇게 말하지만 나는 그것을 볼 기회가 없었습니다.
Jeremy Andrews

1

스위프트 4

"하위 문자열"( https://developer.apple.com/documentation/swift/substring ) :

let greeting = "Hi there! It's nice to meet you! 👋"
let endOfSentence = greeting.index(of: "!")!
let firstSentence = greeting[...endOfSentence]
// firstSentence == "Hi there!"

확장 문자열의 예 :

private typealias HowDoYouLikeThatElonMusk = String
private extension HowDoYouLikeThatElonMusk {

    subscript(_ from: Character?, _ to: Character?, _ include: Bool) -> String? {
        if let _from: Character = from, let _to: Character = to {
            let dynamicSourceForEnd: String = (_from == _to ? String(self.reversed()) : self)
            guard let startOfSentence: String.Index = self.index(of: _from),
                let endOfSentence: String.Index = dynamicSourceForEnd.index(of: _to) else {
                return nil
            }

            let result: String = String(self[startOfSentence...endOfSentence])
            if include == false {
                guard result.count > 2 else {
                        return nil
                }
                return String(result[result.index(result.startIndex, offsetBy: 1)..<result.index(result.endIndex, offsetBy: -1)])
            }
            return result
        } else if let _from: Character = from {
            guard let startOfSentence: String.Index = self.index(of: _from) else {
                return nil
            }
            let result: String = String(self[startOfSentence...])
            if include == false {
                guard result.count > 1 else {
                    return nil
                }
                return String(result[result.index(result.startIndex, offsetBy: 1)...])
            }
            return result
        } else if let _to: Character = to {
            guard let endOfSentence: String.Index = self.index(of: _to) else {
                    return nil
            }
            let result: String = String(self[...endOfSentence])
            if include == false {
                guard result.count > 1 else {
                    return nil
                }
                return String(result[..<result.index(result.endIndex, offsetBy: -1)])
            }
            return result
        }
        return nil
    }
}

확장 문자열을 사용하는 예 :

let source =                                   ">>>01234..56789<<<"
// include = true
var from =          source["3", nil, true]  //       "34..56789<<<"
var to =            source[nil, "6", true]  // ">>>01234..56"
var fromTo =        source["3", "6", true]  //       "34..56"
let notFound =      source["a", nil, true]  // nil
// include = false
from =              source["3", nil, false] //        "4..56789<<<"
to =                source[nil, "6", false] // ">>>01234..5"
fromTo =            source["3", "6", false] //        "4..5"
let outOfBounds =   source[".", ".", false] // nil

let str = "Hello, playground"
let hello = str[nil, ",", false] // "Hello"

-1

Swift 5
let desiredIndex: Int = 7 let substring = str[String.Index(encodedOffset: desiredIndex)...]
이 부분 문자열 변수는 결과를 제공합니다.
여기서 Int는 Index로 변환 된 다음 문자열을 분할 할 수 있습니다. 오류가 발생하지 않으면


2
이것은 잘못이다. 문자는 하나 이상의 바이트로 구성 될 수 있습니다. ASCII 텍스트에서만 작동합니다.
Leo Dabus
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.