如何使用 swift 中的“ä”之类的变音符号拆分字符串

how to split a string with Umlaut like "ä" in swift

我正在编写 swift 5 搜索例程,如果搜索包含在此字符串中,我想在字符串中突出显示(例如,如果我在类似“äbcdef”的字符串中搜索“bcd” “结果应该看起来像“äbcdef”。在这样做的过程中,我为字符串编写了一个扩展,以便在与搜索字符串 (="before") 匹配之前将字符串拆分为子字符串) ,与搜索字符串 (="match") 和之后的子字符串 (="after") 的匹配。

extension String {


func findSubstring(forSearchStr search: String, caseSensitive sensitive: Bool) -> (before: String, match: String, after: String) {
    
        var before = self
        var searchStr = search
        if !sensitive {
            before = before.lowercased()
            searchStr = searchStr.lowercased()
        }
        var match = ""
        var after = ""
        let totalStringlength = before.count
        let searchStringlength = searchStr.count
        var startpos = self.startIndex
        var endpos = self.endIndex
        for id in 0 ... (totalStringlength - searchStringlength) {
            startpos = self.index(self.startIndex, offsetBy: id)
            endpos = self.index(startpos, offsetBy: searchStringlength)
            if searchStr == String(before[startpos ..< endpos]) {
                before = String(self[self.startIndex ..< startpos])
                match = String(self[startpos ..< endpos])
                if id < totalStringlength - searchStringlength - 1 {
                    startpos = self.index(startpos, offsetBy: searchStringlength)
                    after = String(self[startpos ..< self.endIndex])
                }
                break
            }
        }
        return (before, match, after)
    } // end findSubstring()

}

我的问题是,此例程适用于所有不带特殊字符(如德语变音符号“ä、ö、ü”或“ß”)的字符串。如果字符串包含这些字符之一,则返回的子字符串“match”和“after”向右移动一个符号。在上面的示例中,搜索“bcd”的结果在本例中为“äbcdef”

我的问题是,我该怎么做才能正确处理这些字符?

顺便说一下:有没有比我的更简单的解决方案来拆分字符串,而不是我编写的程序(在我看来这似乎相当复杂:))

感谢您的宝贵支持

字符串比较是一个复杂的问题,除非你正在研究它,否则你不会想自己处理的。

只需使用String.range(of:options:):

extension String {
    func findSubstring(forSearchStr search: String, caseSensitive sensitive: Bool) -> (before: String, match: String, after: String)? {
        if let substringRange = range(of: search, options: sensitive ? [] : [.caseInsensitive], locale: nil) {
            return (String(self[startIndex..<substringRange.lowerBound]),
                    String(self[substringRange]),
                    String(self[substringRange.upperBound..<self.endIndex]))
        } else {
            return nil
        }
    }
}

// (before: "ä", match: "bcd", after: "e")
print("äbcde".findSubstring(forSearchStr: "bcd", caseSensitive: true)!)

请注意,这不是字面比较。例如:

// prints (before: "", match: "ß", after: "")
print("ß".findSubstring(forSearchStr: "ss", caseSensitive: false)!)

如果您想要文字比较,请使用 literal 选项:

range(of: search, options: sensitive ? [.literal] : [.caseInsensitive, .literal])