在Swift字符串中查找字符的索引

222

是时候承认失败了...

在Objective-C中,我可以使用类似以下的内容:

NSString* str = @"abcdefghi";
[str rangeOfString:@"c"].location; // 2

在Swift中,我看到了类似的东西:

var str = "abcdefghi"
str.rangeOfString("c").startIndex

...但是它只会给我一个 String.Index,我可以用它来对原始字符串进行下标访问,但无法提取位置。

顺便说一句,那个String.Index有一个私有ivar叫做_position,其中包含了正确的值。我只是不知道它如何被公开。

我知道我可以很容易地将其添加到String中。 我更好奇的是,这个新API中我错过了什么。


这是一个 GitHub 项目,其中包含了许多用于 Swift 字符串操作的扩展方法:https://github.com/iamjono/SwiftString - RenniePet
我找到的最佳实现在这里:https://dev59.com/g1wY5IYBdhLWcg3ws5oF#32306142 - Carlos García
你需要区分Unicode代码点和扩展字形簇吗? - Ky -
33个回答

0
关于将 String.Index 转换为 Int,这个扩展对我很有用:
public extension Int {
    /// Creates an `Int` from a given index in a given string
    ///
    /// - Parameters:
    ///    - index:  The index to convert to an `Int`
    ///    - string: The string from which `index` came
    init(_ index: String.Index, in string: String) {
        self.init(string.distance(from: string.startIndex, to: index))
    }
}

与此问题相关的示例用法:

var testString = "abcdefg"

Int(testString.range(of: "c")!.lowerBound, in: testString)     // 2

testString = "‍‍‍\u{1112}\u{1161}\u{11AB}"

Int(testString.range(of: "")!.lowerBound, in: testString) // 0
Int(testString.range(of: "‍‍‍")!.lowerBound, in: testString)    // 1
Int(testString.range(of: "한")!.lowerBound, in: testString)    // 5

重要提示:

正如您所看到的,它与String.Index不同地分组扩展字形群集和连接字符。当然,这就是为什么我们有String.Index。您应该记住,此方法将群集视为单个字符,这更接近正确。 如果您的目标是按Unicode代码点拆分字符串,则此方法不适用于您。


-1
    // Using Swift 4, the code below works.
    // The problem is that String.index is a struct. Use dot notation to grab the integer part of it that you want: ".encodedOffset"
    let strx = "0123456789ABCDEF"
    let si = strx.index(of: "A")
    let i = si?.encodedOffset       // i will be an Int. You need "?" because it might be nil, no such character found.

    if i != nil {                   // You MUST deal with the optional, unwrap it only if not nil.
        print("i = ",i)
        print("i = ",i!)            // "!" str1ps off "optional" specification (unwraps i).
            // or
        let ii = i!
        print("ii = ",ii)

    }
    // Good luck.

-1

Swift 3

extension String {
        func substring(from:String) -> String
        {
            let searchingString = from
            let rangeOfSearchingString = self.range(of: searchingString)!
            let indexOfSearchingString: Int = self.distance(from: self.startIndex, to: rangeOfSearchingString.upperBound )
            let trimmedString = self.substring(start: indexOfSearchingString , end: self.count)
            
            return trimmedString
        }
        
    }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接