iOS 分詞處理

在搜索等場景,需要對完成的字符串進(jìn)行分詞處理,iOS 自帶兩種分詞方式 NaturalLanguageCFStringTokenizer

蘋果這邊 對于分詞可以選擇對于的模式,常用的是以詞為單位,比如 工作質(zhì)量會拆分成 工作和質(zhì)量。當(dāng)然 對于多語言來說,蘋果這邊支持的也較好,iOS 的Emoji也能識別出來。(特殊字符比如 , / ` 這些符合系統(tǒng)不會識別)

代碼如下:

import Foundation
import NaturalLanguage
import CoreText

extension String {
    public func NLTokenizer() -> [String] {
        let tokenizer = NLTokenizer(unit: .word)
        tokenizer.string = self
        var keyWords: [String] = []

        tokenizer.enumerateTokens(in: startIndex..<endIndex) { tokenRange, _ in
            keyWords.append(String(self[tokenRange]))
            return true
        }
        return keyWords
    }
}

需要注意的是以上代碼的運(yùn)行結(jié)果并不包括系統(tǒng)未識別的的部分。

這里用CFStringTokenizer 單獨(dú)給出包含原字符串所有的分詞結(jié)果。

例如:今天天氣不錯,我們一起出去玩啊?

上面代碼給出的結(jié)果是 今天 天氣 不錯 我們 一起 出去 玩 啊

下面代碼給出的結(jié)果是 今天 天氣 不錯 , 我們 一起 出去 玩 啊 ?


extension String {
    public func cStringTokenizer() -> [String] {
        let cString = self as CFString
        let nsString = self as NSString
        let cStringCount = nsString.length
        let ref = CFStringTokenizerCreate(
            nil,
            cString,
            CFRangeMake(0, cStringCount),
            kCFStringTokenizerUnitWord,
            CFLocaleCopyCurrent()
        )
        CFStringTokenizerAdvanceToNextToken(ref)
        var range: CFRange = CFStringTokenizerGetCurrentTokenRange(ref)
        var keywords: [String] = []
        var preTokenEndIndex: Int = -1
        while range.length > 0 {
            let defaultIndex = preTokenEndIndex + 1
            if defaultIndex < range.location {
                let ignoredRange = NSRange(
                    location: defaultIndex,
                    length: range.location - defaultIndex
                )
                let ignoredString = nsString
                    .substring(with: ignoredRange)
                keywords.append(ignoredString)
            }
            preTokenEndIndex = range.location + range.length - 1

            let keyWord = nsString
                .substring(with: NSRange(location: range.location, length: range.length))
            keywords.append(keyWord)

            CFStringTokenizerAdvanceToNextToken(ref)
            range = CFStringTokenizerGetCurrentTokenRange(ref)
        }

        if preTokenEndIndex + 1 < count {
            let ignoredLocation = preTokenEndIndex + 1
            let ignoredRange = NSRange(location: ignoredLocation, length: count - ignoredLocation)
            let ignoredString = nsString
                .substring(with: ignoredRange)
            keywords.append(ignoredString)
        }

        return keywords
    }
}

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容