不区分大小写的迅速4?

时间:2018-08-05 20:40:48

标签: ios swift

尝试快速拆分值,它可以工作,但是它是cAsE sEnSiTiVe。有没有办法在不区分大小写的情况下迅速拆分它们?

"Hello There!"
"hello there!"

我当前正在使用String.components(seperatedBy: "Th"),但这只会拆分第二个字符串"hello there!"。有没有办法将它们分开?

6 个答案:

答案 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
}