如何使用 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])
我正在编写 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])