如何在iOS中检测文本(字符串)语言?

时间:2017-12-19 15:59:42

标签: ios swift nslinguistictagger

例如,给定以下字符串:

let textEN = "The quick brown fox jumps over the lazy dog"
let textES = "El zorro marrón rápido salta sobre el perro perezoso"
let textAR = "الثعلب البني السريع يقفز فوق الكلب الكسول"
let textDE = "Der schnelle braune Fuchs springt über den faulen Hund"

我想在每个声明的字符串中检测使用过的语言。

我们假设已实现函数的签名是:

func detectedLangauge<T: StringProtocol>(_ forString: T) -> String?
如果没有检测到语言,

会返回可选字符串。

因此适当的结果将是:

let englishDetectedLangauge = detectedLangauge(textEN) // => English
let spanishDetectedLangauge = detectedLangauge(textES) // => Spanish
let arabicDetectedLangauge = detectedLangauge(textAR) // => Arabic
let germanDetectedLangauge = detectedLangauge(textDE) // => German

有没有一种简单的方法来实现它?

3 个答案:

答案 0 :(得分:16)

快速回答:

从iOS 11+开始,您可以使用NSLinguisticTagger来实现它。实现所需的功能:

func detectedLangauge<T: StringProtocol>(_ forString: T) -> String? {
    guard let languageCode = NSLinguisticTagger.dominantLanguage(for: String(forString)) else {
        return nil
    }

    let detectedLangauge = Locale.current.localizedString(forIdentifier: languageCode)

    return detectedLangauge
}

应该达到你要求的目标。


描述答案:

首先,您应该知道您所询问的内容主要与 Natural language processing (NLP) 的世界有关。

由于NLP不仅仅是文本语言检测,因此答案的其余部分将不包含特定的NLP信息。

显然,实现这样的功能并不是那么容易,特别是在开始关注过程的细节时,例如分成句子甚至是单词,在识别名称和标点符号等之后...我打赌你会想到&#34;多么痛苦的过程!我自己这样做是不合逻辑的#34 ;;幸运的是,iOS 支持NLP(实际上,NLP API可用于所有Apple平台,而不仅仅是iOS),以实现您希望易于实现的目标。您将使用的核心组件是NSLinguisticTagger

  

分析自然语言文本以标记词性和词汇类,   识别名称,执行词形还原,并确定语言和   脚本。

     

NSLinguisticTagger提供了各种各样的统一界面   自然语言处理功能,支持许多   不同的语言和脚本。您可以使用此类进行细分   自然语言文本分为段落,句子或单词,以及标签   有关这些细分的信息,例如词性,词汇   类,引理,脚本和语言。

正如课程文档中所提到的,您正在寻找的方法 - 在确定主导语言和正字法部分 - 是dominantLanguage(for:)

  

返回指定字符串的主要语言。

     

     

     

返回值

     

标识字符串主导语言的BCP-47标记,或者   标签&#34; und&#34;如果无法确定特定语言。

您可能会注意到,自从回到iOS 5后,NSLinguisticTagger仍然存在。但是,对于iOS 11及更高版本,dominantLanguage(for:)方法仅 支持}因为它是在Core ML Framework

之上开发的
  

。 。

     

Core ML是特定领域框架的基础   功能。 Core ML支持Vision for image analysis, Foundation   用于自然语言处理(例如,NSLinguisticTagger    class),以及用于评估学习决策树的GameplayKit。核心ML   它本身建立在像Accelerate和BNNS这样的低级原语之上,   以及金属性能着色器。

     

enter image description here

基于通过传递&#34来调用dominantLanguage(for:)的返回值;快速的棕色狐狸跳过懒狗&#34;:

NSLinguisticTagger.dominantLanguage(for: "The quick brown fox jumps over the lazy dog")

将是&#34; en&#34;可选字符串。然而,到目前为止,这不是理想的输出,期望是得到英语&#34;代替!好吧,这正是你应该从localizedString(forLanguageCode:)结构调用Locale方法并传递得到的语言代码所得到的:

Locale.current.localizedString(forIdentifier: "en") // English

全部放在一起:

如&#34;快速回答&#34;代码片段,函数将是:

func detectedLangauge<T: StringProtocol>(_ forString: T) -> String? {
    guard let languageCode = NSLinguisticTagger.dominantLanguage(for: String(forString)) else {
        return nil
    }

    let detectedLangauge = Locale.current.localizedString(forIdentifier: languageCode)

    return detectedLangauge
}

<强>输出:

这将是预期的:

let englishDetectedLangauge = detectedLangauge(textEN) // => English
let spanishDetectedLangauge = detectedLangauge(textES) // => Spanish
let arabicDetectedLangauge = detectedLangauge(textAR) // => Arabic
let germanDetectedLangauge = detectedLangauge(textDE) // => German

请注意:

仍然存在无法获取给定字符串的语言名称的情况,例如:

let textUND = "SdsOE"
let undefinedDetectedLanguage = detectedLangauge(textUND) // => Unknown language

或者甚至可能是nil

let rabish = "000747322"
let rabishDetectedLanguage = detectedLangauge(rabish) // => nil

仍然发现提供有用的输出是一个不错的结果......


此外:

关于NSLinguisticTagger:

虽然我不打算深入研究NSLinguisticTagger用法,但我想指出,其中存在一些非常酷的功能,而不仅仅是检测给定文本的语言;作为一个非常简单的示例:枚举标记时使用引理在使用Information retrieval时会非常有用,因为您可以识别单词&# 34;驱动&#34;通过&#34;驾驶&#34;字。

官方资源

Apple视频会话

另外,为了熟悉CoreML:

答案 1 :(得分:3)

您可以使用NSLinguisticTagger的tagAt方法。它支持iOS 5及更高版本。

func detectLanguage<T: StringProtocol>(for text: T) -> String? {
    let tagger = NSLinguisticTagger.init(tagSchemes: [.language], options: 0)
    tagger.string = String(text)

    guard let languageCode = tagger.tag(at: 0, scheme: .language, tokenRange: nil, sentenceRange: nil) else { return nil }
    return Locale.current.localizedString(forIdentifier: languageCode)
}

detectLanguage(for: "The quick brown fox jumps over the lazy dog")              // English
detectLanguage(for: "El zorro marrón rápido salta sobre el perro perezoso")     // Spanish
detectLanguage(for: "الثعلب البني السريع يقفز فوق الكلب الكسول")                // Arabic
detectLanguage(for: "Der schnelle braune Fuchs springt über den faulen Hund")   // German

答案 2 :(得分:1)

我尝试使用NSLinguisticTagger之类的简短输入文字来hello,它始终被识别为意大利语。 幸运的是,Apple最近添加了NLLanguageRecognizer在iOS 12上可用,并且看起来更准确:D

import NaturalLanguage

if #available(iOS 12.0, *) {
    let languageRecognizer = NLLanguageRecognizer()
    languageRecognizer.processString(text)
    let code = languageRecognizer.dominantLanguage!.rawValue
    let language = Locale.current.localizedString(forIdentifier: code)
}