SwiftUI应用中无空格文本分词问题:NaturalLanguage API失效如何解决?
解决SwiftUI中无空格英文文本的分词问题
为什么你的NLTokenizer方案无效
NLTokenizer的.word单元依赖空格、标点等分隔符以及预设的词边界规则识别单词。对于完全无空格的连续文本(比如HELLOMYFRIENDS),它会将整个字符串视为单个token,自然无法拆分出独立单词。
不需要完全自建词典的解决方案
苹果的NaturalLanguage框架提供了NLLanguageModel,它基于统计语言模型,可以预测文本中最可能的词边界,非常适合处理无空格连续文本。
代码实现
import NaturalLanguage func insertSpacesUsingLanguageModel(in continuousText: String) -> String? { // 加载英文语言模型 guard let languageModel = NLLanguageModel(language: .english) else { return nil } let lowercaseText = continuousText.lowercased() var currentPosition = lowercaseText.startIndex var spacedResult = "" while currentPosition < lowercaseText.endIndex { var highestProbability = Double.leastNormalMagnitude var bestWordRange = currentPosition..<currentPosition // 限制单次尝试的最大字符数(英文单词最长通常不超过20个字符) let maxPossibleLength = min(20, lowercaseText.distance(from: currentPosition, to: lowercaseText.endIndex)) // 遍历所有可能的子串长度,找出概率最高的单词 for length in 1...maxPossibleLength { let endPosition = lowercaseText.index(currentPosition, offsetBy: length) let candidateWord = lowercaseText[currentPosition..<endPosition] if let probability = languageModel.probability(of: String(candidateWord)) { if probability > highestProbability { highestProbability = probability bestWordRange = currentPosition..<endPosition } } } if bestWordRange.isEmpty { // 找不到匹配单词时,直接取单个字符 spacedResult += String(continuousText[currentPosition]) + " " currentPosition = lowercaseText.index(after: currentPosition) } else { // 还原原文本的大小写格式 let originalWord = continuousText[currentPosition..<bestWordRange.upperBound] spacedResult += originalWord + " " currentPosition = bestWordRange.upperBound } } return spacedResult.trimmingCharacters(in: .whitespaces) }
调用示例
if let spacedSentence = insertSpacesUsingLanguageModel(in: "HELLOMYFRIENDS") { print(spacedSentence) // 输出: HELLO MY FRIENDS }
进阶优化:自定义词汇支持
如果你的场景涉及专业术语、自定义词汇,系统模型可能无法准确识别,可以创建自定义语言模型:
- 准备一个包含所有自定义词汇的文本文件(每行一个单词)
- 使用
NLLanguageModelTrainingData导入该文件,训练自定义模型 - 替换代码中的
NLLanguageModel(language: .english)为自定义模型
总结
不需要完全自建词典,利用系统提供的NLLanguageModel就能解决通用英文无空格文本的分词需求;仅在有特定词汇场景时,才需要补充自定义词典来提升准确率。
内容的提问来源于stack exchange,提问作者willwade
相关产品推荐
相关产品推荐

