Swift : 문자의 처음부터 마지막 ​​인덱스까지 부분 문자열을 얻는 방법


110

문자열을 다른 문자열로 바꾸는 가장 좋은 / 간단한 방법을 배우고 싶지만 하위 집합 만 사용하여 문자의 시작 부분에서 시작하여 마지막 인덱스로 이동합니다.

예를 들어 "www.stackoverflow.com"을 "www.stackoverflow"로 변환합니다. 어떤 코드 스 니펫이이를 수행하고 가장 신속하게 처리 할 수 ​​있습니까? (나는 이것이 논쟁을 불러 일으키지 않기를 바라지 만, Swift에서 부분 문자열을 처리하는 방법에 대한 좋은 교훈을 찾을 수 없습니다.

답변:


202

뒤로 접근

가장 좋은 방법은 속성과 전역 함수를 substringToIndex결합 하여 사용 endIndex하는 advance것입니다.

var string1 = "www.stackoverflow.com"

var index1 = advance(string1.endIndex, -4)

var substring1 = string1.substringToIndex(index1)

뒤에서 시작하는 문자열을 찾고

사용 rangeOfString및 설정 options.BackwardsSearch

var string2 = "www.stackoverflow.com"

var index2 = string2.rangeOfString(".", options: .BackwardsSearch)?.startIndex

var substring2 = string2.substringToIndex(index2!)

확장 없음, 순수한 관용적 Swift

스위프트 2.0

advance이제의 일부 Index이며이라고 advancedBy합니다. 다음과 같이합니다.

var string1 = "www.stackoverflow.com"

var index1 = string1.endIndex.advancedBy(-4)

var substring1 = string1.substringToIndex(index1)

스위프트 3.0

당신은 호출 할 수 없습니다 advancedByA의 String는 가변 크기의 요소를 가지고 있기 때문이다. 을 사용해야 index(_, offsetBy:)합니다.

var string1 = "www.stackoverflow.com"

var index1 = string1.index(string1.endIndex, offsetBy: -4)

var substring1 = string1.substring(to: index1)

많은 것들이 이름이 바뀌 었습니다. 사건은 낙타 표기법으로 작성되어, startIndex되었다 lowerBound.

var string2 = "www.stackoverflow.com"

var index2 = string2.range(of: ".", options: .backwards)?.lowerBound

var substring2 = string2.substring(to: index2!)

또한 force unwrapping을 권장하지 않습니다 index2. 선택적 바인딩 또는 map. 개인적으로 다음을 선호합니다 map.

var substring3 = index2.map(string2.substring(to:))

스위프트 4

Swift 3 버전은 여전히 ​​유효하지만 이제 인덱스 범위와 함께 아래 첨자를 사용할 수 있습니다.

let string1 = "www.stackoverflow.com"

let index1 = string1.index(string1.endIndex, offsetBy: -4)

let substring1 = string1[..<index1]

두 번째 접근 방식은 변경되지 않습니다.

let string2 = "www.stackoverflow.com"

let index2 = string2.range(of: ".", options: .backwards)?.lowerBound

let substring3 = index2.map(string2.substring(to:))

1
@ fpg1503 감사합니다. 이것이 제가 찾고자했던 대답입니다. 다른 답변은 나에게 가르쳐 주거나 언어의 기능을 상기시켜 주었지만 이것이 문제를 해결하는 데 사용할 방법입니다.
Jason Hocker 2015 년

1
string1.endIndex.advancedBy(-4)대신 Swift 2.0을 사용 하고 있습니다.advance
Alex Koshy 2015 년

92
이것을 간단히 할 방법이 정말로 없습니까?
devios1

12
@devios 모두 사실입니다. Objective-C에 비해 Swift에 대해 감사하지만 IMHO는이 미친 듯이 어색한 코드로 이어지는 우려는 99 %의 코드와 코더와 관련이 없습니다. 더 나쁜 것은 우리가 스스로 불편한 확장 기능을 작성하게 될 것입니다. 일반 개발자가 이러한 높은 수준의 문제를 이해할 수없는 경우 소프트웨어를 만드는 보행자 문제를 처리하기 위해 임시 API를 작성할 수있는 최소 권한입니다. NSString결국 우리 모두 재단 (레거시) 수업에서 벗어나고 싶어하기 때문에 로 전환하는 경향 도 분명히 나쁩니다. 그래서 .... 더 외침!
Dan Rosenstark

2
Swift 4에서는 string1[..<index1]. 에 대한 필요가 없습니다 string1.startIndex.
bauerMusic

26

스위프트 3, XCode 8

func lastIndexOfCharacter(_ c: Character) -> Int? {
    return range(of: String(c), options: .backwards)?.lowerBound.encodedOffset
}

advancedBy(Int)Swift 3은 String's method를 사용 하기 때문에 사라졌습니다 index(String.Index, Int). String하위 문자열 및 친구들과 함께이 확장을 확인하십시오 .

public extension String {

    //right is the first encountered string after left
    func between(_ left: String, _ right: String) -> String? {
        guard let leftRange = range(of: left), let rightRange = range(of: right, options: .backwards)
        , leftRange.upperBound <= rightRange.lowerBound
            else { return nil }

        let sub = self.substring(from: leftRange.upperBound)
        let closestToLeftRange = sub.range(of: right)!
        return sub.substring(to: closestToLeftRange.lowerBound)
    }

    var length: Int {
        get {
            return self.characters.count
        }
    }

    func substring(to : Int) -> String {
        let toIndex = self.index(self.startIndex, offsetBy: to)
        return self.substring(to: toIndex)
    }

    func substring(from : Int) -> String {
        let fromIndex = self.index(self.startIndex, offsetBy: from)
        return self.substring(from: fromIndex)
    }

    func substring(_ r: Range<Int>) -> String {
        let fromIndex = self.index(self.startIndex, offsetBy: r.lowerBound)
        let toIndex = self.index(self.startIndex, offsetBy: r.upperBound)
        return self.substring(with: Range<String.Index>(uncheckedBounds: (lower: fromIndex, upper: toIndex)))
    }

    func character(_ at: Int) -> Character {
        return self[self.index(self.startIndex, offsetBy: at)]
    }

    func lastIndexOfCharacter(_ c: Character) -> Int? {
        guard let index = range(of: String(c), options: .backwards)?.lowerBound else
        { return nil }
        return distance(from: startIndex, to: index)
    }
}

Swift 4의 업데이트 된 확장

public extension String {

    //right is the first encountered string after left
    func between(_ left: String, _ right: String) -> String? {
        guard
            let leftRange = range(of: left), let rightRange = range(of: right, options: .backwards)
            , leftRange.upperBound <= rightRange.lowerBound
            else { return nil }

        let sub = self[leftRange.upperBound...]
        let closestToLeftRange = sub.range(of: right)!            
        return String(sub[..<closestToLeftRange.lowerBound])
    }

    var length: Int {
        get {
            return self.count
        }
    }

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

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

    func substring(_ r: Range<Int>) -> String {
        let fromIndex = self.index(self.startIndex, offsetBy: r.lowerBound)
        let toIndex = self.index(self.startIndex, offsetBy: r.upperBound)
        let indexRange = Range<String.Index>(uncheckedBounds: (lower: fromIndex, upper: toIndex))
        return String(self[indexRange])
    }

    func character(_ at: Int) -> Character {
        return self[self.index(self.startIndex, offsetBy: at)]
    }

    func lastIndexOfCharacter(_ c: Character) -> Int? {
        guard let index = range(of: String(c), options: .backwards)?.lowerBound else
        { return nil }
        return distance(from: startIndex, to: index)
    }
}

용법:

let text = "www.stackoverflow.com"
let at = text.character(3) // .
let range = text.substring(0..<3) // www
let from = text.substring(from: 4) // stackoverflow.com
let to = text.substring(to: 16) // www.stackoverflow
let between = text.between(".", ".") // stackoverflow
let substringToLastIndexOfChar = text.lastIndexOfCharacter(".") // 17

추신 : 개발자 String.Index가 평범한 대신 처리하도록 강요 한 것은 정말 이상합니다 Int. String단순한 substring()방법 이 아닌 내부 역학에 신경을 써야하는 이유는 무엇 입니까?


encodedOffset이 댓글을 확인하고 해당 stackoverflow.com/questions/34540185/…
Leo Dabus

18

아래 첨자 ( s[start..<end])를 사용하여 수행합니다 .

스위프트 3, 4, 5

let s = "www.stackoverflow.com"
let start = s.startIndex
let end = s.index(s.endIndex, offsetBy: -4)
let substring = s[start..<end] // www.stackoverflow

11

편집 / 업데이트 :

이후 스위프트 4 (엑스 코드 10.0+) 새 사용할 수 있습니다 BidirectionalCollection의 방법 으로 (는 lastIndex를 :)

func lastIndex(of element: Element) -> Int?

let string = "www.stackoverflow.com"
if let lastIndex = string.lastIndex(of: ".") {
    let subString = string[..<lastIndex]  // "www.stackoverflow"
}

이것은 훌륭한 대답이지만 Swift 2에서는이 속성이 NSUrl로 옮겨진 것 같습니다. 아마도 이것은 사람들이 미래에 이것을 읽는 데 도움이 될 것입니다 ...
chuky

8

방법은 다음과 같습니다. 같은 방식으로 할 수도 있고 아이디어를 위해이 코드를 사용할 수도 있습니다.

let s = "www.stackoverflow.com"
s.substringWithRange(0..<s.lastIndexOf("."))

내가 사용하는 확장 프로그램은 다음과 같습니다.

import Foundation
extension String {

  var length: Int {
    get {
      return countElements(self)
    }
  }

  func indexOf(target: String) -> Int {
    var range = self.rangeOfString(target)
    if let range = range {
      return distance(self.startIndex, range.startIndex)
    } else {
      return -1
    }
  }

  func indexOf(target: String, startIndex: Int) -> Int {
    var startRange = advance(self.startIndex, startIndex)        
    var range = self.rangeOfString(target, options: NSStringCompareOptions.LiteralSearch, range: Range<String.Index>(start: startRange, end: self.endIndex))
    if let range = range {
      return distance(self.startIndex, range.startIndex)
    } else {
      return -1
    }
  }

  func lastIndexOf(target: String) -> Int {
    var index = -1
    var stepIndex = self.indexOf(target)
    while stepIndex > -1 {
      index = stepIndex
      if stepIndex + target.length < self.length {
        stepIndex = indexOf(target, startIndex: stepIndex + target.length)
      } else {
        stepIndex = -1
      }
    }
    return index
  } 

  func substringWithRange(range:Range<Int>) -> String {
    let start = advance(self.startIndex, range.startIndex)
    let end = advance(self.startIndex, range.endIndex)
    return self.substringWithRange(start..<end)
  }

}

Credit albertbori / Common Swift String Extensions

일반적으로 저는 특히 문자열 조작, 검색 및 슬라이싱과 같은 요구 사항에 대해 확장을 강력하게지지합니다.


2
저는 이것이 Swift에서 String의 API를 개선하기 위해 Apple이 실제로해야 할 일이라고 생각합니다.
skyline75489 2015 년

2
이 API를 찾고 있습니다. Apple Swift에는 기본 API가 많이 부족합니다. 매우 복잡한 언어이며 완전하지도 않습니다. Swift는 헛소리입니다!
Loc

다음은 참조하는 라이브러리의 Swift 3 버전으로 분기되고 업데이트 된 것입니다. github.com/iamjono/SwiftString
RenniePet

5

String 내장 하위 문자열 기능이 있습니다.

extension String : Sliceable {
    subscript (subRange: Range<String.Index>) -> String { get }
}

원하는 것이 " 문자 의 첫 번째 인덱스로 이동"하는 것이라면 내장 find()함수를 사용하여 하위 문자열을 얻을 수 있습니다 .

var str = "www.stackexchange.com"
str[str.startIndex ..< find(str, ".")!] // -> "www"

마지막 인덱스 를 찾으려면 findLast().

/// Returns the last index where `value` appears in `domain` or `nil` if
/// `value` is not found.
///
/// Complexity: O(\ `countElements(domain)`\ )
func findLast<C: CollectionType where C.Generator.Element: Equatable>(domain: C, value: C.Generator.Element) -> C.Index? {
    var last:C.Index? = nil
    for i in domain.startIndex..<domain.endIndex {
        if domain[i] == value {
            last = i
        }
    }
    return last
}

let str = "www.stackexchange.com"
let substring = map(findLast(str, ".")) { str[str.startIndex ..< $0] } // as String?
// if "." is found, substring has some, otherwise `nil`

추가됨 :

아마도의 BidirectionalIndexType특수 버전 findLast이 더 빠를 것입니다.

func findLast<C: CollectionType where C.Generator.Element: Equatable, C.Index: BidirectionalIndexType>(domain: C, value: C.Generator.Element) -> C.Index? {
    for i in lazy(domain.startIndex ..< domain.endIndex).reverse() {
        if domain[i] == value {
            return i
        }
    }
    return nil
}

String의 첨자는 Swift 2.0에서 사용할 수없는 것 같습니다. 대체 할 것을 알고 있습니까?
Cory

Swift 4 이상에서 Index를 BidirectionalIndexType으로 제한하는 방법을 알고 있습니까?
Leo Dabus

5

다음 확장을 사용할 수 있습니다.

스위프트 2.3

 extension String
    {
        func substringFromIndex(index: Int) -> String
        {
            if (index < 0 || index > self.characters.count)
            {
                print("index \(index) out of bounds")
                return ""
            }
            return self.substringFromIndex(self.startIndex.advancedBy(index))
        }

        func substringToIndex(index: Int) -> String
        {
            if (index < 0 || index > self.characters.count)
            {
                print("index \(index) out of bounds")
                return ""
            }
            return self.substringToIndex(self.startIndex.advancedBy(index))
        }

        func substringWithRange(start: Int, end: Int) -> String
        {
            if (start < 0 || start > self.characters.count)
            {
                print("start index \(start) out of bounds")
                return ""
            }
            else if end < 0 || end > self.characters.count
            {
                print("end index \(end) out of bounds")
                return ""
            }
            let range = Range(start: self.startIndex.advancedBy(start), end: self.startIndex.advancedBy(end))
            return self.substringWithRange(range)
        }

        func substringWithRange(start: Int, location: Int) -> String
        {
            if (start < 0 || start > self.characters.count)
            {
                print("start index \(start) out of bounds")
                return ""
            }
            else if location < 0 || start + location > self.characters.count
            {
                print("end index \(start + location) out of bounds")
                return ""
            }
            let range = Range(start: self.startIndex.advancedBy(start), end: self.startIndex.advancedBy(start + location))
            return self.substringWithRange(range)
        }
    }

스위프트 3

extension String
{   
    func substring(from index: Int) -> String
    {
        if (index < 0 || index > self.characters.count)
        {
            print("index \(index) out of bounds")
            return ""
        }
        return self.substring(from: self.characters.index(self.startIndex, offsetBy: index))
    }

    func substring(to index: Int) -> String
    {
        if (index < 0 || index > self.characters.count)
        {
            print("index \(index) out of bounds")
            return ""
        }
        return self.substring(to: self.characters.index(self.startIndex, offsetBy: index))
    }

    func substring(start: Int, end: Int) -> String
    {
        if (start < 0 || start > self.characters.count)
        {
            print("start index \(start) out of bounds")
            return ""
        }
        else if end < 0 || end > self.characters.count
        {
            print("end index \(end) out of bounds")
            return ""
        }
        let startIndex = self.characters.index(self.startIndex, offsetBy: start)
        let endIndex = self.characters.index(self.startIndex, offsetBy: end)
        let range = startIndex..<endIndex

        return self.substring(with: range)
    }

    func substring(start: Int, location: Int) -> String
    {
        if (start < 0 || start > self.characters.count)
        {
            print("start index \(start) out of bounds")
            return ""
        }
        else if location < 0 || start + location > self.characters.count
        {
            print("end index \(start + location) out of bounds")
            return ""
        }
        let startIndex = self.characters.index(self.startIndex, offsetBy: start)
        let endIndex = self.characters.index(self.startIndex, offsetBy: start + location)
        let range = startIndex..<endIndex

        return self.substring(with: range)
    }
}

용법:

let string = "www.stackoverflow.com"        
let substring = string.substringToIndex(string.characters.count-4)

5

스위프트 4 :

extension String {

    /// the length of the string
    var length: Int {
        return self.characters.count
    }

    /// Get substring, e.g. "ABCDE".substring(index: 2, length: 3) -> "CDE"
    ///
    /// - parameter index:  the start index
    /// - parameter length: the length of the substring
    ///
    /// - returns: the substring
    public func substring(index: Int, length: Int) -> String {
        if self.length <= index {
            return ""
        }
        let leftIndex = self.index(self.startIndex, offsetBy: index)
        if self.length <= index + length {
            return self.substring(from: leftIndex)
        }
        let rightIndex = self.index(self.endIndex, offsetBy: -(self.length - index - length))
        return self.substring(with: leftIndex..<rightIndex)
    }

    /// Get substring, e.g. -> "ABCDE".substring(left: 0, right: 2) -> "ABC"
    ///
    /// - parameter left:  the start index
    /// - parameter right: the end index
    ///
    /// - returns: the substring
    public func substring(left: Int, right: Int) -> String {
        if length <= left {
            return ""
        }
        let leftIndex = self.index(self.startIndex, offsetBy: left)
        if length <= right {
            return self.substring(from: leftIndex)
        }
        else {
            let rightIndex = self.index(self.endIndex, offsetBy: -self.length + right + 1)
            return self.substring(with: leftIndex..<rightIndex)
        }
    }
}

다음과 같이 테스트 할 수 있습니다.

    print("test: " + String("ABCDE".substring(index: 2, length: 3) == "CDE"))
    print("test: " + String("ABCDE".substring(index: 0, length: 3) == "ABC"))
    print("test: " + String("ABCDE".substring(index: 2, length: 1000) == "CDE"))
    print("test: " + String("ABCDE".substring(left: 0, right: 2) == "ABC"))
    print("test: " + String("ABCDE".substring(left: 1, right: 3) == "BCD"))
    print("test: " + String("ABCDE".substring(left: 3, right: 1000) == "DE"))

https://gitlab.com/seriyvolk83/SwiftEx 라이브러리를 확인 하십시오 . 여기에는 이러한 방법과 기타 유용한 방법이 포함되어 있습니다.


4

시작 인덱스에서 문자 중 하나의 마지막 인덱스까지 문자열의 하위 문자열을 가져 오시겠습니까? 그렇다면 다음 Swift 2.0+ 방법 중 하나를 선택할 수 있습니다.

필요한 방법 Foundation

문자의 마지막 색인을 포함하는 하위 문자열을 가져옵니다.

import Foundation

let string = "www.stackoverflow.com"
if let rangeOfIndex = string.rangeOfCharacterFromSet(NSCharacterSet(charactersInString: "."), options: .BackwardsSearch) {
    print(string.substringToIndex(rangeOfIndex.endIndex))
}

// prints "www.stackoverflow."

문자의 마지막 색인을 포함하지 않는 하위 문자열을 가져옵니다.

import Foundation

let string = "www.stackoverflow.com"
if let rangeOfIndex = string.rangeOfCharacterFromSet(NSCharacterSet(charactersInString: "."), options: .BackwardsSearch) {
    print(string.substringToIndex(rangeOfIndex.startIndex))
}

// prints "www.stackoverflow"

이러한 작업을 반복해야하는 경우 확장 String이 좋은 솔루션이 될 수 있습니다.

import Foundation

extension String {
    func substringWithLastInstanceOf(character: Character) -> String? {
        if let rangeOfIndex = rangeOfCharacterFromSet(NSCharacterSet(charactersInString: String(character)), options: .BackwardsSearch) {
            return self.substringToIndex(rangeOfIndex.endIndex)
        }
        return nil
    }
    func substringWithoutLastInstanceOf(character: Character) -> String? {
        if let rangeOfIndex = rangeOfCharacterFromSet(NSCharacterSet(charactersInString: String(character)), options: .BackwardsSearch) {
            return self.substringToIndex(rangeOfIndex.startIndex)
        }
        return nil
    }
}

print("www.stackoverflow.com".substringWithLastInstanceOf("."))
print("www.stackoverflow.com".substringWithoutLastInstanceOf("."))

/*
prints:
Optional("www.stackoverflow.")
Optional("www.stackoverflow")
*/

필요하지 않은 방법 Foundation

문자의 마지막 색인을 포함하는 하위 문자열을 가져옵니다.

let string = "www.stackoverflow.com"
if let reverseIndex = string.characters.reverse().indexOf(".") {
    print(string[string.startIndex ..< reverseIndex.base])
}

// prints "www.stackoverflow."

문자의 마지막 색인을 포함하지 않는 하위 문자열을 가져옵니다.

let string = "www.stackoverflow.com"
if let reverseIndex = string.characters.reverse().indexOf(".") {
    print(string[string.startIndex ..< reverseIndex.base.advancedBy(-1)])
}

// prints "www.stackoverflow"

이러한 작업을 반복해야하는 경우 확장 String이 좋은 솔루션이 될 수 있습니다.

extension String {
    func substringWithLastInstanceOf(character: Character) -> String? {
        if let reverseIndex = characters.reverse().indexOf(".") {
            return self[self.startIndex ..< reverseIndex.base]
        }
        return nil
    }
    func substringWithoutLastInstanceOf(character: Character) -> String? {
        if let reverseIndex = characters.reverse().indexOf(".") {
            return self[self.startIndex ..< reverseIndex.base.advancedBy(-1)]
        }
        return nil
    }
}

print("www.stackoverflow.com".substringWithLastInstanceOf("."))
print("www.stackoverflow.com".substringWithoutLastInstanceOf("."))

/*
prints:
Optional("www.stackoverflow.")
Optional("www.stackoverflow")
*/

4

색인을 알고있는 경우 하위 문자열을 얻는 쉽고 짧은 방법은 다음과 같습니다.

let s = "www.stackoverflow.com"
let result = String(s.characters.prefix(17)) // "www.stackoverflow"

색인이 문자열 길이를 초과하는 경우 앱이 중단되지 않습니다.

let s = "short"
let result = String(s.characters.prefix(17)) // "short"

두 예제 모두 Swift 3를 지원 합니다.


4

덜컥 거리는 소리를 추가하는 한 가지는 반복입니다 stringVar.

stringVar [ stringVar .index ( stringVar .startIndex, offsetBy : ...)

에서 스위프트 4

확장은 다음 중 일부를 줄일 수 있습니다.

extension String {

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

그런 다음 사용법 :

let string = "abcde"

let to = string[..<string.index(at: 3)] // abc
let from = string[string.index(at: 3)...] // de

또한 주목해야한다 tofrom타입 Substring(또는 String.SubSequance). 새 문자열을 할당하지 않으며 처리에 더 효율적입니다.

백 얻으려면 String입력하면 Substring다시 주조 할 필요가 String:

let backToString = String(from)

마지막으로 문자열이 할당되는 곳입니다.


3
func substr(myString: String, start: Int, clen: Int)->String

{
  var index2 = string1.startIndex.advancedBy(start)
  var substring2 = string1.substringFromIndex(index2)
  var index1 = substring2.startIndex.advancedBy(clen)
  var substring1 = substring2.substringToIndex(index1)

  return substring1   
}

substr(string1, start: 3, clen: 5)

3

스위프트 3

let string = "www.stackoverflow.com"
let first3Characters = String(string.characters.prefix(3)) // www
let lastCharacters = string.characters.dropFirst(4) // stackoverflow.com (it would be a collection)

//or by index 
let indexOfFouthCharacter = olNumber.index(olNumber.startIndex, offsetBy: 4)
let first3Characters = olNumber.substring(to: indexOfFouthCharacter) // www
let lastCharacters = olNumber.substring(from: indexOfFouthCharacter) // .stackoverflow.com

이해하기 좋은 기사 , 왜 이것이 필요한가요?


2

두 개의 하위 문자열 메서드로 String을 확장했습니다. 다음과 같이 시작 / 끝 범위 또는 시작 / 길이로 하위 문자열을 호출 할 수 있습니다.

var bcd = "abcdef".substring(1,to:3)
var cde = "abcdef".substring(2,to:-2)
var cde = "abcdef".substring(2,length:3)

extension String {
  public func substring(from:Int = 0, var to:Int = -1) -> String {
    if to < 0 {
        to = self.length + to
    }
    return self.substringWithRange(Range<String.Index>(
        start:self.startIndex.advancedBy(from),
        end:self.startIndex.advancedBy(to+1)))
  }
  public func substring(from:Int = 0, length:Int) -> String {
    return self.substringWithRange(Range<String.Index>(
        start:self.startIndex.advancedBy(from),
        end:self.startIndex.advancedBy(from+length)))
  }
}

self.length는 더 이상 사용할 수 없습니다. 확장 기능에 이것을 추가해야합니다 (Andrewz, 코드를 업데이트하십시오. 다른 답변을 게시하고 싶지 않습니다) : public func length ()-> Int {return self.lengthOfBytesUsingEncoding (NSUTF16StringEncoding)}
philippe

1

Swift 2.0 아래 코드는 XCode 7.2에서 테스트되었습니다. 하단에 첨부 된 스크린 샷을 참조하세요.

import UIKit

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        var mainText = "http://stackoverflow.com"

        var range = Range(start: mainText.startIndex.advancedBy(7), end: mainText.startIndex.advancedBy(24))
        var subText = mainText.substringWithRange(range)


        //OR Else use below for LAST INDEX

        range = Range(start: mainText.startIndex.advancedBy(7), end: mainText.endIndex)
        subText = mainText.substringWithRange(range)
    }
}

1

Swift 5에서

String.IndexIndex를 표현하기 위해서는 단순한 Int 값 대신에 필요 합니다.

또한 Swift String(값 유형) 에서 subString을 얻으려고 할 때 실제로 유형 대신 유형 Sequence을 반환하는 프로토콜 로 반복해야 합니다 .String.SubSequenceString

다시 얻으려면 String에서 String.SubSequence사용String(subString)

아래의 예 :

    let string = "https://stackoverflow.com"
    let firstIndex = String.Index(utf16Offset: 0, in: string)
    let lastIndex = String.Index(utf16Offset: 6, in: string)
    let subString = String(string[firstIndex...lastIndex])

0

들어 스위프트 2.0 ,이 같다 :

var string1 = "www.stackoverflow.com"
var index1 = string1.endIndex.advancedBy(-4)
var substring1 = string1.substringToIndex(index1)

아마도 그들은 그것을 변경했지만 그것은 'advancedBy'입니다 ( 'advanced'의 끝에있는 'd'에주의하십시오)
Wedge Martin

0

andrewz의 게시물을 Swift 2.0 (및 아마도 Swift 3.0)과 호환되도록 수정했습니다. 겸손하게 생각하면이 확장은 이해하기 쉽고 다른 언어 (예 : PHP) 에서 사용할 수있는 것과 유사합니다 .

extension String {

    func length() -> Int {
        return self.lengthOfBytesUsingEncoding(NSUTF16StringEncoding)
    }
    func substring(from:Int = 0, to:Int = -1) -> String {
       var nto=to
        if nto < 0 {
            nto = self.length() + nto
        }
        return self.substringWithRange(Range<String.Index>(
           start:self.startIndex.advancedBy(from),
           end:self.startIndex.advancedBy(nto+1)))
    }
    func substring(from:Int = 0, length:Int) -> String {
        return self.substringWithRange(Range<String.Index>(
            start:self.startIndex.advancedBy(from),
            end:self.startIndex.advancedBy(from+length)))
    }
}

0

또한 Swift 4를위한 간단한 문자열 확장을 빌드합니다.

extension String {
    func subStr(s: Int, l: Int) -> String { //s=start, l=lenth
        let r = Range(NSRange(location: s, length: l))!
        let fromIndex = self.index(self.startIndex, offsetBy: r.lowerBound)
        let toIndex = self.index(self.startIndex, offsetBy: r.upperBound)
        let indexRange = Range<String.Index>(uncheckedBounds: (lower: fromIndex, upper: toIndex))

        return String(self[indexRange])
     }
}

따라서 다음과 같이 쉽게 부를 수 있습니다.

"Hallo world".subStr(s: 1, l: 3) //prints --> "all"

0

Int-based해결 방법을 시도하십시오 .

extension String {
    // start and end is included
    func intBasedSubstring(_ start: Int, _ end: Int) -> String {
        let endOffset: Int = -(count - end - 1)
        let startIdx = self.index(startIndex, offsetBy: start)
        let endIdx = self.index(endIndex, offsetBy: endOffset)
        return String(self[startIdx..<endIdx])
    }
}

참고 : 그것은 단지 연습 일뿐입니다. 경계를 확인하지 않습니다. 필요에 맞게 수정하십시오.


-1

Swift에서 하위 문자열을 얻는 간단한 방법은 다음과 같습니다.

import UIKit

var str = "Hello, playground" 
var res = NSString(string: str)
print(res.substring(from: 4))
print(res.substring(to: 10))

OP는 사전 정의 된 하드 코딩 된 값을 사용하여 하위 문자열을 가져 오는 방법이 아니라 "문자의 처음부터 마지막 ​​색인까지 하위 문자열을 가져 오는 방법"을 묻습니다.
에릭 아야

이것은 원래의 예입니다. "www.stackoverflow.com"을 "www.stackoverflow"로 변환합니다. 시작부터 끝까지 하위 문자열을 원하면 할 일이 없습니다. 즉, 결과는 그대로 입력 문자열입니다. 위 답변의 유용성을 회복 해주세요.
ZagorTeNej
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.