尝试快速拆分值,它可以工作,但是它是cAsE sEnSiTiVe。有没有办法在不区分大小写的情况下迅速拆分它们?
"Hello There!"
"hello there!"
我当前正在使用String.components(seperatedBy: "Th")
,但这只会拆分第二个字符串"hello there!"
。有没有办法将它们分开?
答案 0 :(得分:3)
您可以这样写:
import Foundation
let str1 = "Hello There!"
let str2 = "hello there!"
extension String {
func caseInsensitiveSplit(separator: String) -> [String] {
//Thanks for Carpsen90. Please see comments below.
if separator.isEmpty {
return [self] //generates the same output as `.components(separatedBy: "")`
}
let pattern = NSRegularExpression.escapedPattern(for: separator)
let regex = try! NSRegularExpression(pattern: pattern, options: .caseInsensitive)
let matches = regex.matches(in: self, options: [], range: NSRange(0..<self.utf16.count))
let ranges = (0..<matches.count+1).map { (i: Int)->NSRange in
let start = i == 0 ? 0 : matches[i-1].range.location + matches[i-1].range.length
let end = i == matches.count ? self.utf16.count: matches[i].range.location
return NSRange(location: start, length: end-start)
}
return ranges.map {String(self[Range($0, in: self)!])}
}
}
print( str1.caseInsensitiveSplit(separator: "th") ) //->["Hello ", "ere!"]
print( str2.caseInsensitiveSplit(separator: "th") ) //->["hello ", "ere!"]
但是我不知道您想对"hello "
和"ere!"
做什么。
(如果分隔符与"th"
,"tH"
,"Th"
或"TH"
匹配,则会丢失分隔符的大小写信息。)
如果您可以解释自己真正想做的事情,那么有人会为您提供更好的解决方案。
答案 1 :(得分:2)
只是为了娱乐另一个使用NSRegularExpression的版本,但扩展了StringProtocol:
快速4或更高版本
extension StringProtocol {
func caseInsensitiveComponents<T>(separatedBy separator: T) -> [SubSequence] where T: StringProtocol, Index == String.Index {
var index = startIndex
return ((try? NSRegularExpression(pattern: NSRegularExpression.escapedPattern(for: String(separator)), options: .caseInsensitive))?.matches(in: String(self), range: NSRange(location: 0, length: utf16.count))
.compactMap {
guard let range = Range($0.range, in: String(self))
else { return nil }
defer { index = range.upperBound }
return self[index..<range.lowerBound]
} ?? []) + [self[index...]]
}
}
游乐场测试
let str1 = "Hello There!"
let str2 = "hello there!"
str1.caseInsensitiveComponents(separatedBy: "Th") // ["Hello ", "ere!"]
str2.caseInsensitiveComponents(separatedBy: "Th") // ["Hello ", "ere!"]
答案 2 :(得分:0)
您可以先将整个字符串小写:
let s = "Hello There!".lowercased().components(separatedBy: "th")
答案 3 :(得分:0)
不确定我是否理解您要实现的目标,但是您可以尝试一下。
var str = "Hello There!"
var str2 = "hello there!"
override func viewDidLoad() {
super.viewDidLoad()
let split1 = str.lowercased().replacingOccurrences(of: "th", with: " ")
let split2 = str2.lowercased().replacingOccurrences(of: "th", with: " ")
print(split1) //hello ere!
print(split2) //hello ere!
}
答案 4 :(得分:0)
一种可能的解决方案是使用range
选项获取分隔符的.caseInsensitive
并从其lower-
和upperBound
中提取子字符串。
extension StringProtocol where Index == String.Index {
func caseInsensitiveComponents(separatedBy separator: String) -> [SubSequence]
{
var result = [SubSequence]()
var currentIndex = startIndex
while let separatorRange = self[currentIndex...].range(of: separator, options: .caseInsensitive) {
result.append(self[currentIndex..<separatorRange.lowerBound])
currentIndex = separatorRange.upperBound
}
return result + [self[currentIndex...]]
}
}
答案 5 :(得分:0)
如果要过滤包含某个关键字的项目列表,则拆分字符串是错误的方法。您只需要简单检查一下该关键字是否出现在项目中:
let queryStr = "th"
let items = [
"Hello There!",
"hello there!"
]
let filterdItems = items.filter {
return $0.range(of: queryStr, options: .caseInsensitive) != nil
}