在Swift编程语言中获取字符串的第n个字符

时间:2014-06-07 01:50:32

标签: swift string collections character

如何获取字符串的第n个字符?我尝试了托架([])访问器而没有运气。

var string = "Hello, world!"

var firstChar = string[0] // Throws error
  

错误:'下标'不可用:不能使用Int下标String,请参阅文档注释以供讨论

46 个答案:

答案 0 :(得分:533)

注意:有关Swift 4的正确实施,请参阅Leo Dabus' answer

Swift 4

在Swift 4中引入了Substring类型来创建子串 通过与原始字符串共享存储来更快,更高效,这就是下标函数应返回的内容。

尝试here

extension String {
  subscript (i: Int) -> Character {
    return self[index(startIndex, offsetBy: i)]
  }
  subscript (bounds: CountableRange<Int>) -> Substring {
    let start = index(startIndex, offsetBy: bounds.lowerBound)
    let end = index(startIndex, offsetBy: bounds.upperBound)
    return self[start ..< end]
  }
  subscript (bounds: CountableClosedRange<Int>) -> Substring {
    let start = index(startIndex, offsetBy: bounds.lowerBound)
    let end = index(startIndex, offsetBy: bounds.upperBound)
    return self[start ... end]
  }
  subscript (bounds: CountablePartialRangeFrom<Int>) -> Substring {
    let start = index(startIndex, offsetBy: bounds.lowerBound)
    let end = index(endIndex, offsetBy: -1)
    return self[start ... end]
  }
  subscript (bounds: PartialRangeThrough<Int>) -> Substring {
    let end = index(startIndex, offsetBy: bounds.upperBound)
    return self[startIndex ... end]
  }
  subscript (bounds: PartialRangeUpTo<Int>) -> Substring {
    let end = index(startIndex, offsetBy: bounds.upperBound)
    return self[startIndex ..< end]
  }
}
extension Substring {
  subscript (i: Int) -> Character {
    return self[index(startIndex, offsetBy: i)]
  }
  subscript (bounds: CountableRange<Int>) -> Substring {
    let start = index(startIndex, offsetBy: bounds.lowerBound)
    let end = index(startIndex, offsetBy: bounds.upperBound)
    return self[start ..< end]
  }
  subscript (bounds: CountableClosedRange<Int>) -> Substring {
    let start = index(startIndex, offsetBy: bounds.lowerBound)
    let end = index(startIndex, offsetBy: bounds.upperBound)
    return self[start ... end]
  }
  subscript (bounds: CountablePartialRangeFrom<Int>) -> Substring {
    let start = index(startIndex, offsetBy: bounds.lowerBound)
    let end = index(endIndex, offsetBy: -1)
    return self[start ... end]
  }
  subscript (bounds: PartialRangeThrough<Int>) -> Substring {
    let end = index(startIndex, offsetBy: bounds.upperBound)
    return self[startIndex ... end]
  }
  subscript (bounds: PartialRangeUpTo<Int>) -> Substring {
    let end = index(startIndex, offsetBy: bounds.upperBound)
    return self[startIndex ..< end]
  }
}

要将Substring转换为String,您可以简单地完成 做String(string[0..2]),但你应该这样做,如果 你计划保持子串。否则,它会更多 有效保持Substring

如果有人能想出一个合并的好方法,那将会很棒 将这两个扩展合二为一。我试过扩展StringProtocol 没有成功,因为那里不存在index方法。

Swift 3:

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

为什么这不是内置的?

Apple提供以下说明(found here):

  

无法使用整数订阅字符串。

     

“字符串中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代码单元的术语。例如,实例   NSRangeNSAttributedStringNSRegularExpression一起使用   String.unicodeScalars存储子字符串偏移量和长度   UTF-16代码单元的术语。

  •   
  • String.characters是Unicode标量的集合。   在执行低级操作时使用此API   字符数据。

  •   
  • String.localizedStandardCompare()是扩展字形的集合   群集,是用户感知的近似值   字符。

  •   
     

请注意,在处理包含人类可读文本的字符串时,   应尽量避免逐字符处理   可能。例如,使用高级语言环境敏感的Unicode算法,   String.localizedLowercaseString,   String.localizedStandardRangeOfString(),   {{1}}等。

答案 1 :(得分:309)

Swift 4.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"

您需要将此String扩展名添加到您的项目中(它已经过全面测试):

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扩展),我仍然强烈推荐使用扩展名。为什么?因为它从早期版本的Swift中节省了数十小时的痛苦迁移,其中String的语法几乎每个版本都在改变,但我需要做的就是更新扩展的实现而不是重构整个300k行代码生产应用程序。做出你的选择。

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"

答案 2 :(得分:124)

我想出了这个简洁的解决方法

var firstChar = Array(string)[0]

答案 3 :(得分:122)

不使用整数进行索引,仅使用String.Index。主要是线性复杂性。您还可以从String.Index创建范围并使用它们获取子字符串。

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

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

答案 4 :(得分:96)

Xcode 10.2•Swift 5

您可以扩展Swift 4的StringProtocol,使下标也可用于子字符串。注意: 由于提案SE-0191,可以删除对IndexDistance == Int的扩展限制:

extension StringProtocol {        
    subscript(offset: Int) -> Element {
        return self[index(startIndex, offsetBy: offset)]
    }
    subscript(_ range: Range<Int>) -> SubSequence {
        return prefix(range.lowerBound + range.count)
            .suffix(range.count)
    }
    subscript(range: ClosedRange<Int>) -> SubSequence {
        return prefix(range.lowerBound + range.count)
            .suffix(range.count)
    }
    subscript(range: PartialRangeThrough<Int>) -> SubSequence {
        return prefix(range.upperBound.advanced(by: 1))
    }
    subscript(range: PartialRangeUpTo<Int>) -> SubSequence {
        return prefix(range.upperBound)
    }
    subscript(range: PartialRangeFrom<Int>) -> SubSequence {
        return suffix(Swift.max(0, count - range.lowerBound))
    }
}
extension LosslessStringConvertible {
    var string: String { return .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 you need to add .string as follow
test[10...].string  // "!!! Hello Brazil !!!"

答案 5 :(得分:56)

Swift 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"

第一个字符

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"

Swift 2和3

str = "My String"

**索引处的字符串**

Swift 2

let charAtIndex = String(str[str.startIndex.advancedBy(3)])  // charAtIndex = "S"

Swift 3

str[str.index(str.startIndex, offsetBy: 3)]

SubString fromIndex toIndex

Swift 2

let subStr = str[str.startIndex.advancedBy(3)...str.startIndex.advancedBy(7)] // subStr = "Strin"

Swift 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"

答案 6 :(得分:24)

Xcode 7 GM Seed的Swift 2.0

var text = "Hello, world!"

let firstChar = text[text.startIndex.advancedBy(0)] // "H"

对于第n个字符,将0替换为n-1。

编辑:Swift 3.0

text[text.index(text.startIndex, offsetBy: 0)]


注:有更简单的方法来抓取字符串中的某些字符

e.g。 let firstChar = text.characters.first

答案 7 :(得分:23)

如果您看到Cannot subscript a value of type 'String'...使用此扩展程序:

Swift 3

extension String {
    subscript (i: Int) -> Character {
        return self[self.characters.index(self.startIndex, offsetBy: i)]
    }

    subscript (i: Int) -> String {
        return String(self[i] as Character)
    }

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

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

Swift 2.3

extension String {
    subscript(integerIndex: Int) -> Character {
        let index = advance(startIndex, integerIndex)
        return self[index]
    }

    subscript(integerRange: Range<Int>) -> String {
        let start = advance(startIndex, integerRange.startIndex)
        let end = advance(startIndex, integerRange.endIndex)
        let range = start..<end
        return self[range]
    }
}

来源:http://oleb.net/blog/2014/07/swift-strings/

答案 8 :(得分:19)

Swift 2.2解决方案:

以下扩展在Xcode 7中有效,这是this解决方案和Swift 2.0语法转换的组合。

extension String {
    subscript(integerIndex: Int) -> Character {
        let index = startIndex.advancedBy(integerIndex)
        return self[index]
    }

    subscript(integerRange: Range<Int>) -> String {
        let start = startIndex.advancedBy(integerRange.startIndex)
        let end = startIndex.advancedBy(integerRange.endIndex)
        let range = start..<end
        return self[range]
    }
}

答案 9 :(得分:11)

swift字符串类不提供在特定索引处获取字符的能力,因为它本身支持UTF字符。内存中UTF字符的可变长度使得直接跳转到字符是不可能的。这意味着您每次都必须手动循环遍历字符串。

您可以扩展String以提供一种循环字符的方法,直到您想要的索引

extension String {
    func characterAtIndex(index: Int) -> Character? {
        var cur = 0
        for char in self {
            if cur == index {
                return char
            }
            cur++
        }
        return nil
    }
}

myString.characterAtIndex(0)!

答案 10 :(得分:11)

Swift 4

String(Array(stringToIndex)[index]) 

这可能是一次性解决此问题的最佳方法。您可能希望先将String转换为数组,然后再将结果转换为String。否则,将返回一个Character而不是String。

示例String(Array("HelloThere")[1])将返回&#34; e&#34;作为一个字符串。

(Array("HelloThere")[1]将返回&#34; e&#34;作为一个角色。

Swift不允许将字符串像数组一样编入索引,但这可以完成工作,蛮力风格。

答案 11 :(得分:11)

另外,有一些函数可以直接应用于String的Character-chain表示,如下所示:

var string = "Hello, playground"
let firstCharacter = string.characters.first // returns "H"
let lastCharacter = string.characters.last // returns "d"

结果是Character类型,但您可以将其强制转换为String。

或者这个:

let reversedString = String(string.characters.reverse())
// returns "dnuorgyalp ,olleH" 

: - )

答案 12 :(得分:5)

Swift 5.3

我认为这很优雅。解决此问题的方法是“与Swift合作”的Paul Hudson的荣誉:

@available (macOS 10.15, * )
extension String {
    subscript(idx: Int) -> String {
        String(self[index(startIndex, offsetBy: idx)])
    }
}

然后只需从字符串中提取一个字符即可:

var string = "Hello, world!"

var firstChar = string[0] // No error, returns "H" as a String

答案 13 :(得分:5)

我遇到了同样的问题。只需这样做:

var aString: String = "test"
var aChar:unichar = (aString as NSString).characterAtIndex(0)

答案 14 :(得分:3)

我非常简单的解决方案:

let myString = "Test string"
let index = 0
let firstCharacter = myString[String.Index(encodedOffset: index)]

答案 15 :(得分:3)

<强> Swift3

您可以使用下标语法在特定的String索引处访问Character。

let greeting = "Guten Tag!"
let index = greeting.index(greeting.startIndex, offsetBy: 7)
greeting[index] // a

访问https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/StringsAndCharacters.html

或者我们可以在 Swift 4

中进行字符串扩展
extension String {
    func getCharAtIndex(_ index: Int) -> Character {
        return self[self.index(self.startIndex, offsetBy: index)]
    }
}

用法:

let foo = "ABC123"
foo.getCharAtIndex(2) //C

答案 16 :(得分:3)

我的解决方案是一行,假设cadena是字符串,4是你想要的第n个位置:

let character = cadena[advance(cadena.startIndex, 4)]

简单......我想Swift将在未来版本中包含更多关于子串的内容。

答案 17 :(得分:3)

您可以通过将String转换为Array并通过使用下标的特定索引来获取它,如下所示:

var str = "Hello"
let s = Array(str)[2]
print(s)

答案 18 :(得分:3)

Swift 3:另一种解决方案(在游乐场测试)

extension String {
    func substr(_ start:Int, length:Int=0) -> String? {
        guard start > -1 else {
            return nil
        }

        let count = self.characters.count - 1

        guard start <= count else {
            return nil
        }

        let startOffset = max(0, start)
        let endOffset = length > 0 ? min(count, startOffset + length - 1) : count

        return self[self.index(self.startIndex, offsetBy: startOffset)...self.index(self.startIndex, offsetBy: endOffset)]
    }
}

用法:

let txt = "12345"

txt.substr(-1) //nil
txt.substr(0) //"12345"
txt.substr(0, length: 0) //"12345"
txt.substr(1) //"2345"
txt.substr(2) //"345"
txt.substr(3) //"45"
txt.substr(4) //"5"
txt.substr(6) //nil
txt.substr(0, length: 1) //"1"
txt.substr(1, length: 1) //"2"
txt.substr(2, length: 1) //"3"
txt.substr(3, length: 1) //"4"
txt.substr(3, length: 2) //"45"
txt.substr(3, length: 3) //"45"
txt.substr(4, length: 1) //"5"
txt.substr(4, length: 2) //"5"
txt.substr(5, length: 1) //nil
txt.substr(5, length: -1) //nil
txt.substr(-1, length: -1) //nil

答案 19 :(得分:2)

获取&amp;设置下标(String&amp; Substring) - Swift 4.2

Swift 4.2,Xcode 10

我的回答是基于@alecarlson的回答。 唯一的重大区别是您可以获得List configData = await loadAsset(); print(configData[0]); Substring返回(在某些情况下,还有一个String)。 您还可以Characterget下标。 最后,我的答案比@alecarlson更麻烦,更长,因此,我建议你把它放在一个源文件中。

扩展:

set

答案 20 :(得分:2)

Swift 4

使用String&#39; s indices属性

的范围和部分范围下标

作为@LeoDabus nice answer的变体,我们可能会向DefaultBidirectionalIndices添加一个额外的扩展名,目的是允许我们在实现自定义下标时使用indices property of String({{1}后者的专门范围和部分范围。

Int

感谢@LeoDabus指导我使用extension DefaultBidirectionalIndices { subscript(at: Int) -> Elements.Index { return index(startIndex, offsetBy: at) } } // Moving the index(_:offsetBy:) to an extension yields slightly // briefer implementations for these String extensions. extension String { subscript(r: CountableClosedRange<Int>) -> SubSequence { return self[indices[r.lowerBound]...indices[r.upperBound]] } subscript(r: CountablePartialRangeFrom<Int>) -> SubSequence { return self[indices[r.lowerBound]...] } subscript(r: PartialRangeThrough<Int>) -> SubSequence { return self[...indices[r.upperBound]] } subscript(r: PartialRangeUpTo<Int>) -> SubSequence { return self[..<indices[r.upperBound]] } } let str = "foo bar baz bax" print(str[4...6]) // "bar" print(str[4...]) // "bar baz bax" print(str[...6]) // "foo bar" print(str[..<6]) // "foo ba" 属性作为indices下标的(其他)替代方法!

Swift 4.2。

在Swift 4.2中,DefaultBidirectionalIndices已被弃用,转而使用DefaultIndices

答案 21 :(得分:2)

雨燕4.2

这个答案很理想,因为它在一个扩展名中扩展了String及其所有SubsequencesSubstring

public extension StringProtocol {

    public subscript (i: Int) -> Element {
        return self[index(startIndex, offsetBy: i)]
    }

    public subscript (bounds: CountableClosedRange<Int>) -> SubSequence {
        let start = index(startIndex, offsetBy: bounds.lowerBound)
        let end = index(startIndex, offsetBy: bounds.upperBound)
        return self[start...end]
    }

    public subscript (bounds: CountableRange<Int>) -> SubSequence {
        let start = index(startIndex, offsetBy: bounds.lowerBound)
        let end = index(startIndex, offsetBy: bounds.upperBound)
        return self[start..<end]
    }

    public subscript (bounds: PartialRangeUpTo<Int>) -> SubSequence {
        let end = index(startIndex, offsetBy: bounds.upperBound)
        return self[startIndex..<end]
    }

    public subscript (bounds: PartialRangeThrough<Int>) -> SubSequence {
        let end = index(startIndex, offsetBy: bounds.upperBound)
        return self[startIndex...end]
    }

    public subscript (bounds: CountablePartialRangeFrom<Int>) -> SubSequence {
        let start = index(startIndex, offsetBy: bounds.lowerBound)
        return self[start..<endIndex]
    }
}

用法

var str = "Hello, playground"

print(str[5...][...5][0])
// Prints ","

答案 22 :(得分:2)

Swift 3

extension String {

    public func charAt(_ i: Int) -> Character {
        return self[self.characters.index(self.startIndex, offsetBy: i)]
    }

    public subscript (i: Int) -> String {
        return String(self.charAt(i) as Character)
    }

    public subscript (r: Range<Int>) -> String {
        return substring(with: self.characters.index(self.startIndex, offsetBy: r.lowerBound)..<self.characters.index(self.startIndex, offsetBy: r.upperBound))
    }

    public subscript (r: CountableClosedRange<Int>) -> String {
        return substring(with: self.characters.index(self.startIndex, offsetBy: r.lowerBound)..<self.characters.index(self.startIndex, offsetBy: r.upperBound))
    }

}

<强>用法

let str = "Hello World"
let sub = str[0...4]

Helpful Programming Tips and Tricks (written by me)

答案 23 :(得分:2)

我认为获得第一个角色的快速答案可能是:

let firstCharacter = aString[aString.startIndex]

它的优雅和性能比:

let firstCharacter = Array(aString.characters).first

但是......如果你想操纵并用字符串做更多的操作,你可以认为创建一个扩展。这种方法有一个扩展,它与已在这里发布的非常相似:

extension String {
var length : Int {
    return self.characters.count
}

subscript(integerIndex: Int) -> Character {
    let index = startIndex.advancedBy(integerIndex)
    return self[index]
}

subscript(integerRange: Range<Int>) -> String {
    let start = startIndex.advancedBy(integerRange.startIndex)
    let end = startIndex.advancedBy(integerRange.endIndex)
    let range = start..<end
    return self[range]
}

}

但这是一个令人难以置信的想法!

下面的扩展非常低效。每次使用整数访问字符串时,都会运行O(n)函数来提升其起始索引。在另一个线性循环内运行线性循环意味着这个for循环意外地为O(n2) - 随着字符串长度的增加,这个循环所需的时间呈二次方增长。

您可以使用字符的字符串集合而不是这样做。

答案 24 :(得分:2)

在Swift 5中,没有扩展到String

var str = "ABCDEFGH"
for char in str {
if(char == "C") { }
}

上述Swift代码与Java代码相同:

int n = 8;
var str = "ABCDEFGH"
for (int i=0; i<n; i++) {
if (str.charAt(i) == 'C') { }
}

答案 25 :(得分:2)

雨燕5.1.3:

添加字符串扩展名:

extension String {

 func stringAt(_ i: Int) -> String { 
   return String(Array(self)[i]) 
 } 

 func charAt(_ i: Int) -> Character { 
  return Array(self)[i] 
 } 
}

let str = "Teja Kumar"
let str1: String = str.stringAt(2)  //"j"
let str2: Character = str.charAt(5)  //"k"

答案 26 :(得分:2)

更新swift 2.0 subString

public extension String {
    public subscript (i: Int) -> String {
        return self.substringWithRange(self.startIndex..<self.startIndex.advancedBy(i + 1))
    }

    public subscript (r: Range<Int>) -> String {
        get {
            return self.substringWithRange(self.startIndex.advancedBy(r.startIndex)..<self.startIndex.advancedBy(r.endIndex))
        }
    }

}

答案 27 :(得分:2)

为了提供主题并显示快速的下标可能性,这里有一个小字符串&#34; substring-toolbox&#34;基于下标

这些方法是安全的,永远不会超过字符串索引

extension String {
    // string[i] -> one string char
    subscript(pos: Int) -> String { return String(Array(self)[min(self.length-1,max(0,pos))]) }

    // string[pos,len] -> substring from pos for len chars on the left
    subscript(pos: Int, len: Int) -> String { return self[pos, len, .pos_len, .left2right] }

    // string[pos, len, .right2left] -> substring from pos for len chars on the right
    subscript(pos: Int, len: Int, way: Way) -> String { return self[pos, len, .pos_len, way] }

    // string[range] -> substring form start pos on the left to end pos on the right
    subscript(range: Range<Int>) -> String { return self[range.startIndex, range.endIndex, .start_end, .left2right] }

    // string[range, .right2left] -> substring start pos on the right to end pos on the left
    subscript(range: Range<Int>, way: Way) -> String { return self[range.startIndex, range.endIndex, .start_end, way] }

    var length: Int { return countElements(self) }
    enum Mode { case pos_len, start_end }
    enum Way { case left2right, right2left }
    subscript(var val1: Int, var val2: Int, mode: Mode, way: Way) -> String {
        if mode == .start_end {
            if val1 > val2 { let val=val1 ; val1=val2 ; val2=val }
            val2 = val2-val1
        }
        if way == .left2right {
            val1 = min(self.length-1, max(0,val1))
            val2 = min(self.length-val1, max(1,val2))
        } else {
            let val1_ = val1
            val1 = min(self.length-1, max(0, self.length-val1_-val2 ))
            val2 = max(1, (self.length-1-val1_)-(val1-1) )
        }
        return self.bridgeToObjectiveC().substringWithRange(NSMakeRange(val1, val2))

        //-- Alternative code without bridge --
        //var range: Range<Int> = pos...(pos+len-1)
        //var start = advance(startIndex, range.startIndex)
        //var end = advance(startIndex, range.endIndex)
        //return self.substringWithRange(Range(start: start, end: end))
    }
}


println("0123456789"[3]) // return "3"

println("0123456789"[3,2]) // return "34"

println("0123456789"[3,2,.right2left]) // return "56"

println("0123456789"[5,10,.pos_len,.left2right]) // return "56789"

println("0123456789"[8,120,.pos_len,.right2left]) // return "01"

println("0123456789"[120,120,.pos_len,.left2right]) // return "9"

println("0123456789"[0...4]) // return "01234"

println("0123456789"[0..4]) // return "0123"

println("0123456789"[0...4,.right2left]) // return "56789"

println("0123456789"[4...0,.right2left]) // return "678" << because ??? range can wear endIndex at 0 ???

答案 28 :(得分:1)

最适合我的方法是:

var firstName = "Olivia"
var lastName = "Pope"

var nameInitials.text = "\(firstName.prefix(1))" + "\    (lastName.prefix(1))"

输出:“ OP”

答案 29 :(得分:1)

在没有String类扩展的Swift 3中,尽可能简单!

let myString = "abcedfg"
let characterLocationIndex = myString.index(myString.startIndex, offsetBy: 3)
let myCharacter = myString[characterLocationIndex]
在这个例子中,

myCharacter是“3”。

答案 30 :(得分:1)

有另一种选择,在String manifesto

中解释
extension String : BidirectionalCollection {
    subscript(i: Index) -> Character { return characters[i] }
}

答案 31 :(得分:1)

这是您可以使用的扩展程序,使用Swift 3.1。单个索引将返回Character,这在索引String时看起来很直观,而Range将返回String

extension String {
    subscript (i: Int) -> Character {
        return Array(self.characters)[i]
    }

    subscript (r: CountableClosedRange<Int>) -> String {
        return String(Array(self.characters)[r])
    }

    subscript (r: CountableRange<Int>) -> String {
        return self[r.lowerBound...r.upperBound-1]
    }
}

行动中的扩展的一些例子:

let string = "Hello"

let c1 = string[1]  // Character "e"
let c2 = string[-1] // fatal error: Index out of range

let r1 = string[1..<4] // String "ell"
let r2 = string[1...4] // String "ello"
let r3 = string[1...5] // fatal error: Array index is out of range


n.b。您可以在上述扩展名中添加其他方法,以便在需要时返回带有单个字符的String

subscript (i: Int) -> String {
    return String(self[i])
}

请注意,在索引字符串时,您必须明确指定所需的类型:

let c: Character = string[3] // Character "l"
let s: String = string[0]    // String "H"

答案 32 :(得分:1)

使用字符可以完成这项工作。您可以快速将 String 转换为可由CharacterView方法操作的字符数组。

示例:

let myString = "Hello World!"
let myChars  = myString.characters

(完整CharacterView doc)

(在Swift 3中测试)

答案 33 :(得分:1)

您还可以将字符串转换为字符数组,如下所示:

let text = "My Text"
let index = 2
let charSequence = text.unicodeScalars.map{ Character($0) }
let char = charSequence[index]

这是在常量时间内在指定索引处获取char的方法。

以下示例不会在恒定时间内运行,但需要线性时间。因此,如果您在String中通过索引进行大量搜索,请使用上述方法。

let char = text[text.startIndex.advancedBy(index)]

答案 34 :(得分:1)

类似python的解决方案,允许您使用否定索引

var str = "Hello world!"
str[-1]        // "!"

可能是:

extension String {
    subscript (var index:Int)->Character{
        get {
            let n = distance(self.startIndex, self.endIndex)
            index %= n
            if index < 0 { index += n }
            return self[advance(startIndex, index)]
        }
    }
}

顺便说一句,转换整个python's slice notation

可能是值得的

答案 35 :(得分:1)

获取第一个字母:

first(str) // retrieve first letter

更多信息: http://sketchytech.blogspot.com/2014/08/swift-pure-swift-method-for-returning.html

答案 36 :(得分:1)

Swift的String类型不提供characterAtIndex方法,因为可以通过多种方式对Unicode字符串进行编码。你选择UTF8,UTF16还是别的什么?

您可以通过检索CodeUnitString.utf8属性来访问String.utf16个收藏集。您还可以通过检索UnicodeScalar属性来访问String.unicodeScalars集合。

本着NSString实施的精神,我将返回unichar类型。

extension String
{
    func characterAtIndex(index:Int) -> unichar
    {
        return self.utf16[index]
    }

    // Allows us to use String[index] notation
    subscript(index:Int) -> unichar
    {
        return characterAtIndex(index)
    }
}

let text = "Hello Swift!"
let firstChar = text[0]

答案 37 :(得分:0)

斯威夫特3:

extension String {
    func substring(fromPosition: UInt, toPosition: UInt) -> String? {
        guard fromPosition <= toPosition else {
            return nil
        }

        guard toPosition < UInt(characters.count) else {
            return nil
        }

        let start = index(startIndex, offsetBy: String.IndexDistance(fromPosition))
        let end   = index(startIndex, offsetBy: String.IndexDistance(toPosition) + 1)
        let range = start..<end

        return substring(with: range)
    }
}

"ffaabbcc".substring(fromPosition: 2, toPosition: 5) // return "aabb"

答案 38 :(得分:0)

允许负面指数

在使用下标扩展时,总是有用并不总是必须编写python my_program.py -h -a来获取最后一个字符。此( Swift 3 )扩展允许负指数,Range和CountableClosedRange。

string[string.length - 1]

如何使用它:

extension String {
    var count: Int { return self.characters.count }

    subscript (i: Int) -> Character {
        // wraps out of bounds indices
        let j = i % self.count
        // wraps negative indices
        let x = j < 0 ? j + self.count : j

        // quick exit for first
        guard x != 0 else {
            return self.characters.first!
        }

        // quick exit for last
        guard x != count - 1 else {
            return self.characters.last!
        }

        return self[self.index(self.startIndex, offsetBy: x)]
    }

    subscript (r: Range<Int>) -> String {
        let lb = r.lowerBound
        let ub = r.upperBound

        // quick exit for one character
        guard lb != ub else { return String(self[lb]) }

        return self[self.index(self.startIndex, offsetBy: lb)..<self.index(self.startIndex, offsetBy: ub)]
    }

    subscript (r: CountableClosedRange<Int>) -> String {
        return self[r.lowerBound..<r.upperBound + 1]
    }
}

对于更全面的程序员:在此扩展程序中对空字符串包含var text = "Hello World" text[-1] // d text[2] // l text[12] // e text[0...4] // Hello text[0..<4] // Hell

guard

答案 39 :(得分:0)

在您的项目中加入此扩展程序

  extension String{
func trim() -> String
{
    return self.trimmingCharacters(in: NSCharacterSet.whitespaces)
}

var length: Int {
    return self.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])
}

func substring(fromIndex: Int, toIndex:Int)->String{
    let startIndex = self.index(self.startIndex, offsetBy: fromIndex)
    let endIndex = self.index(startIndex, offsetBy: toIndex-fromIndex)

    return String(self[startIndex...endIndex])
}

然后使用像这样的功能

let str = "Sample-String"

let substring = str.substring(fromIndex: 0, toIndex: 0) //returns S
let sampleSubstr = str.substring(fromIndex: 0, toIndex: 5) //returns Sample

答案 40 :(得分:0)

我想指出,如果你有一个大字符串并需要随机访问它中的许多字符,你可能需要支付额外的内存成本并将字符串转换为数组以获得更好的性能:

// Pay up front for O(N) memory
let chars = Array(veryLargeString.characters)

for i in 0...veryLargeNumber {
    // Benefit from O(1) access
    print(chars[i])
}

答案 41 :(得分:0)

检查这是Swift 4

let myString = "LOVE"

self.textField1.text = String(Array(myString)[0])
self.textField2.text = String(Array(myString)[1])
self.textField3.text = String(Array(myString)[2])
self.textField4.text = String(Array(myString)[3])

答案 42 :(得分:0)

Swift 5.1

在所有这些答案中,这可能是最简单的解决方案。

添加此扩展名:

            FVector position;
            FRotator rotation;
            int id = tracker.deviceIndex;
            FName srcName = tracker.motionControllerSource;
            bool success = tracker.motionController->GetControllerOrientationAndPosition(id, srcName, rotation, position, 250.0f);
            if (success)
            {
                poseMesh->SetWorldLocationAndRotation(position, rotation);
            }

答案 43 :(得分:0)

目前,下标(_ :)不可用。以及我们做不到的

str[0] 

带有字符串。我们必须提供“ String.Index” 但是,我们如何以这种方式给出自己的索引号,而可以使用

string[str.index(str.startIndex, offsetBy: 0)]

答案 44 :(得分:0)

您可以使用SwiftString(https://github.com/amayne/SwiftString)来执行此操作。

"Hello, world!"[0] // H
"Hello, world!"[0...4] // Hello

免责声明:我写了这个扩展名

答案 45 :(得分:-2)

最好和最简单的方法之一

        let yourString = "thisString"
        print(Array(yourString)[8])

将字符串中的每个字母放入错误 然后你卖出第九个