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

如何获得字符串的第n个字符?我尝试[]没有成功的bracket()访问器。

var string = "Hello, world!"

var firstChar = string[0] // Throws error

错误:“下标”不可用:无法对带Int的字符串进行下标,请参见文档注释以进行讨论

回答:

注意: 请参阅LeoDabus的答案以获取有关Swift 4和Swift5的正确实现。

Xcode 11•Swift 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 ????????!!!"

回答:

这种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)] }

}

要将转换SubstringString,您可以简单地执行String(string[0..2]),但是只有在计划保留子字符串的情况下,才应该这样做。否则,将其保留为更有效Substring

如果有人能想出一种将这两个扩展合并为一个的好方法,那就太好了。 我尝试扩展StringProtocol

失败,因为该index方法不存在。注意:此答案已经过编辑,已经正确实现,现在也适用于子字符串。只需确保使用有效范围避​​免在为您的StringProtocol类型下标时崩溃。对于范围不会超出范围值而不会崩溃的下标,可以使用此实现


回答:

错误消息显示为 “请参阅文档注释以进行讨论”

。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代码单位处理字符串。例如,NSRange用于NSAttributedString

    NSRegularExpression存储以UTF-16代码单位表示的子字符串偏移量和长度的实例 。

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

  • String.characters 是扩展的字素簇的集合,它们是用户感知的字符的近似值。

请注意,在处理包含人类可读文本的字符串时,应尽可能避免逐字符处理。使用高级别语言环境敏感的Unicode算法代替,例如

String.localizedStandardCompare()String.localizedLowercaseString

String.localizedStandardRangeOfString()等。

以上是 在Swift编程语言中获取字符串的第n个字符 的全部内容, 来源链接: utcz.com/qa/417068.html

回到顶部