문자열의 n 번째 문자를 얻으려면 어떻게해야합니까? []
행운이없이 bracket ( ) 접근 자를 시도했습니다 .
var string = "Hello, world!"
var firstChar = string[0] // Throws error
오류 : ‘아래 첨자’를 사용할 수 없습니다 : Int로 문자열을 첨자 할 수 없습니다. 설명서 주석을 참조하십시오.
답변
주의 : Swift 4 및 Swift 5의 올바른 구현에 대해서는 Leo Dabus의 답변 을 참조하십시오 .
스위프트 4 이상
이 Substring
유형은 원본 문자열과 스토리지를 공유하여 하위 문자열을 더 빠르고 효율적으로 만들기 위해 Swift 4에 도입되었으므로 하위 스크립트 함수가 반환해야합니다.
여기서 사용해보십시오
extension StringProtocol {
subscript(offset: Int) -> Character { self[index(startIndex, offsetBy: offset)] }
subscript(range: Range<Int>) -> SubSequence {
let startIndex = index(self.startIndex, offsetBy: range.lowerBound)
return self[startIndex..<index(startIndex, offsetBy: range.count)]
}
subscript(range: ClosedRange<Int>) -> SubSequence {
let startIndex = index(self.startIndex, offsetBy: range.lowerBound)
return self[startIndex..<index(startIndex, offsetBy: range.count)]
}
subscript(range: PartialRangeFrom<Int>) -> SubSequence { self[index(startIndex, offsetBy: range.lowerBound)...] }
subscript(range: PartialRangeThrough<Int>) -> SubSequence { self[...index(startIndex, offsetBy: range.upperBound)] }
subscript(range: PartialRangeUpTo<Int>) -> SubSequence { self[..<index(startIndex, offsetBy: range.upperBound)] }
}
을 변환하려면 Substring
에 String
, 당신은 간단하게 할 수 String(string[0..2])
있지만, 당신은 당신이하려는 경우 주변 하위 문자열 유지하는 것을해야한다. 그렇지 않으면을 유지하는 것이 더 효율적 Substring
입니다.
누군가이 두 확장을 하나로 병합하는 좋은 방법을 알아낼 수 있다면 좋을 것입니다. 방법이 존재하지 참고 :이 답변은 이미 편집되었으며 올바르게 구현되어 이제 하위 문자열에서도 작동합니다. StringProtocol 유형을 첨자화할 때 충돌을 피하려면 유효한 범위를 사용해야합니다. 범위를 벗어난 값으로 충돌하지 않는 범위를 가진 첨자를 위해이 구현을 사용할 수 있습니다StringProtocol
않기 때문에 성공하지 않고 확장 을 시도 index
했습니다.
왜 이것이 내장되어 있지 않습니까?
오류 메시지에 “토론을위한 설명서 주석 참조”가 표시 됩니다. Apple은 UnavailableStringAPIs.swift 파일에 다음 설명을 제공합니다 .
정수로 첨자 문자열을 사용할 수 없습니다.
”
i
문자열의 문자 “개념은 라이브러리 및 시스템 구성 요소에 따라 다르게 해석됩니다. 사용 사례 및 관련 API에 따라 올바른 해석을 선택해야하므로String
정수로 첨자를 사용할 수 없습니다.Swift는 문자열 안에 저장된 문자 데이터에 액세스하는 여러 가지 방법을 제공합니다.
String.utf8
문자열에서 UTF-8 코드 단위의 모음입니다. 문자열을 UTF-8로 변환 할 때이 API를 사용하십시오. 대부분의 POSIX API는 UTF-8 코드 단위로 문자열을 처리합니다.
String.utf16
문자열로 된 UTF-16 코드 단위의 모음입니다. 대부분의 Cocoa 및 Cocoa touch API는 문자열을 UTF-16 코드 단위로 처리합니다. 예를 들어, UTF-16 코드 단위로 하위 문자열 오프셋 및 길이NSRange
와 함께 사용NSAttributedString
및
NSRegularExpression
저장 되는 인스턴스입니다
.
String.unicodeScalars
유니 코드 스칼라의 모음입니다. 문자 데이터의 저수준 조작을 수행 할 때이 API를 사용하십시오.
String.characters
사용자가 인식 한 문자의 근사치 인 확장 된 grapheme 클러스터 모음입니다.사람이 읽을 수있는 텍스트가 포함 된 문자열을 처리 할 때는 문자 별 처리를 최대한 피해야합니다. 대신에 고급 로케일 구분 유니 코드 알고리즘을 사용하십시오 (예
String.localizedStandardCompare()
:
String.localizedLowercaseString
,
String.localizedStandardRangeOfString()
등).
답변
스위프트 5.2
let str = "abcdef"
str[1 ..< 3] // returns "bc"
str[5] // returns "f"
str[80] // returns ""
str.substring(fromIndex: 3) // returns "def"
str.substring(toIndex: str.length - 2) // returns "abcd"
이 문자열 확장을 프로젝트에 추가해야합니다 (완전히 테스트 됨).
extension String {
var length: Int {
return count
}
subscript (i: Int) -> String {
return self[i ..< i + 1]
}
func substring(fromIndex: Int) -> String {
return self[min(fromIndex, length) ..< length]
}
func substring(toIndex: Int) -> String {
return self[0 ..< max(0, toIndex)]
}
subscript (r: Range<Int>) -> String {
let range = Range(uncheckedBounds: (lower: max(0, min(length, r.lowerBound)),
upper: min(length, max(0, r.upperBound))))
let start = index(startIndex, offsetBy: range.lowerBound)
let end = index(start, offsetBy: range.upperBound - range.lowerBound)
return String(self[start ..< end])
}
}
Swift가 항상이 문제에 대한 해결책을 항상 가지고 있었지만 (아래에 제공 한 String 확장명 없음) 여전히 확장명을 사용하는 것이 좋습니다 . 왜? String의 구문이 거의 모든 릴리스에서 변경되는 초기 버전의 Swift에서 수십 시간의 고통스러운 마이그레이션을 절약했기 때문에 전체 프로젝트를 리팩토링하는 대신 확장 구현을 업데이트하기 만하면됩니다. 선택하십시오.
let str = "Hello, world!"
let index = str.index(str.startIndex, offsetBy: 4)
str[index] // returns Character 'o'
let endIndex = str.index(str.endIndex, offsetBy:-2)
str[index ..< endIndex] // returns String "o, worl"
String(str.suffix(from: index)) // returns String "o, world!"
String(str.prefix(upTo: index)) // returns String "Hell"
답변
방금이 깔끔한 해결 방법을 생각해 냈습니다.
var firstChar = Array(string)[0]
답변
정수만 사용하여 인덱싱하지 않고을 사용 String.Index
합니다. 대부분 선형 복잡성. 범위를 작성 String.Index
하고이를 사용하여 하위 문자열을 얻을 수도 있습니다 .
스위프트 3.0
let firstChar = someString[someString.startIndex]
let lastChar = someString[someString.index(before: someString.endIndex)]
let charAtIndex = someString[someString.index(someString.startIndex, offsetBy: 10)]
let range = someString.startIndex..<someString.index(someString.startIndex, offsetBy: 10)
let substring = someString[range]
스위프트 2.x
let firstChar = someString[someString.startIndex]
let lastChar = someString[someString.endIndex.predecessor()]
let charAtIndex = someString[someString.startIndex.advanceBy(10)]
let range = someString.startIndex..<someString.startIndex.advanceBy(10)
let subtring = someString[range]
한 문자열에서 다른 문자열로 생성 된 인덱스 (또는 범위)는 사용할 수 없습니다.
let index10 = someString.startIndex.advanceBy(10)
//will compile
//sometimes it will work but sometimes it will crash or result in undefined behaviour
let charFromAnotherString = anotherString[index10]
답변
Xcode 11 • 스위프트 5.1
StringProtocol을 확장하여 아래 첨자도 아래 첨자를 사용할 수 있습니다.
extension StringProtocol {
subscript(_ offset: Int) -> Element { self[index(startIndex, offsetBy: offset)] }
subscript(_ range: Range<Int>) -> SubSequence { prefix(range.lowerBound+range.count).suffix(range.count) }
subscript(_ range: ClosedRange<Int>) -> SubSequence { prefix(range.lowerBound+range.count).suffix(range.count) }
subscript(_ range: PartialRangeThrough<Int>) -> SubSequence { prefix(range.upperBound.advanced(by: 1)) }
subscript(_ range: PartialRangeUpTo<Int>) -> SubSequence { prefix(range.upperBound) }
subscript(_ range: PartialRangeFrom<Int>) -> SubSequence { suffix(Swift.max(0, count-range.lowerBound)) }
}
extension LosslessStringConvertible {
var string: String { .init(self) }
}
extension BidirectionalCollection {
subscript(safe offset: Int) -> Element? {
guard !isEmpty, let i = index(startIndex, offsetBy: offset, limitedBy: index(before: endIndex)) else { return nil }
return self[i]
}
}
테스팅
let test = "Hello USA ??!!! Hello Brazil ??!!!"
test[safe: 10] // "??"
test[11] // "!"
test[10...] // "??!!! Hello Brazil ??!!!"
test[10..<12] // "??!"
test[10...12] // "??!!"
test[...10] // "Hello USA ??"
test[..<10] // "Hello USA "
test.first // "H"
test.last // "!"
// Subscripting the Substring
test[...][...3] // "Hell"
// Note that they all return a Substring of the original String.
// To create a new String from a substring
test[10...].string // "??!!! Hello Brazil ??!!!"
답변
스위프트 4
let str = "My String"
인덱스의 문자열
let index = str.index(str.startIndex, offsetBy: 3)
String(str[index]) // "S"
부분 문자열
let startIndex = str.index(str.startIndex, offsetBy: 3)
let endIndex = str.index(str.startIndex, offsetBy: 7)
String(str[startIndex...endIndex]) // "Strin"
첫 n 자
let startIndex = str.index(str.startIndex, offsetBy: 3)
String(str[..<startIndex]) // "My "
마지막 n 자
let startIndex = str.index(str.startIndex, offsetBy: 3)
String(str[startIndex...]) // "String"
스위프트 2와 3
str = "My String"
** 지수 문자열 **
스위프트 2
let charAtIndex = String(str[str.startIndex.advancedBy(3)]) // charAtIndex = "S"
스위프트 3
str[str.index(str.startIndex, offsetBy: 3)]
Index to Index to SubString
스위프트 2
let subStr = str[str.startIndex.advancedBy(3)...str.startIndex.advancedBy(7)] // subStr = "Strin"
스위프트 3
str[str.index(str.startIndex, offsetBy: 3)...str.index(str.startIndex, offsetBy: 7)]
첫 n 자
let first2Chars = String(str.characters.prefix(2)) // first2Chars = "My"
마지막 n 자
let last3Chars = String(str.characters.suffix(3)) // last3Chars = "ing"
답변
Xcode 7 GM Seed의 Swift 2.0
var text = "Hello, world!"
let firstChar = text[text.startIndex.advancedBy(0)] // "H"
n 번째 문자의 경우 0을 n-1로 바꾸십시오.
편집 : 스위프트 3.0
text[text.index(text.startIndex, offsetBy: 0)]
nb 문자열에서 특정 문자를 잡는 간단한 방법이 있습니다
예 : let firstChar = text.characters.first