如何计算Swift中String中的单词数?

时间:2017-10-28 02:38:40

标签: swift

说我有一个字符串,我如何确定其中的字数?我试图创建一个像:

这样的扩展程序
extension String {
    var numberOfWords: Int {
        // Insert string-counting code here
    }
}

1 个答案:

答案 0 :(得分:8)

如果你搜索"字数字符串swift"您将找到许多StackOverflow答案和要点,告诉您使用str.components(separatedBy: " ").count拆分字符串。

不要使用components(separatedBy:) !!!

许多非欧洲语言(特别是东亚语言)不会使用空格来分割单词。这也会错误地将带连字符的单词统计为单独的,并将单个标点符号统计为单词。

解决此问题的最正确且最高效的方法是使用enumerateStrings(in:options:)CFStringTokenizer

// enumerateStrings
extension String {
    var numberOfWords: Int {
        var count = 0
        let range = Range(startIndex..<endIndex)
        enumerateSubstrings(in: range, options: [.byWords, .substringNotRequired, .localized], { _, _, _, _ -> () in
            count += 1
        })
        return count
    }
}

OR:

// CFStringTokenizer
extension String {
    var numberOfWords: Int {
        let inputRange = CFRangeMake(0, utf16.count)
        let flag = UInt(kCFStringTokenizerUnitWord)
        let locale = CFLocaleCopyCurrent()
        let tokenizer = CFStringTokenizerCreate(kCFAllocatorDefault, self as CFString, inputRange, flag, locale)
        var tokenType = CFStringTokenizerAdvanceToNextToken(tokenizer)
        var count = 0

        while tokenType != [] {
            count += 1
            tokenType = CFStringTokenizerAdvanceToNextToken(tokenizer)
        }
        return count
    }
}

两者都非常高效,但enumerateSubtrings(in:options:...)大约快两倍。

感到震惊的是没有人在其他地方指出这一点,所以我希望寻找解决方案的人找到这个。