[英]How to detect text (string) language in iOS?
例如,給定以下字符串:
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 detectedLanguage<T: StringProtocol>(_ forString: T) -> String?
如果未檢測到語言,則返回一個可選字符串。
因此,適當的結果是:
let englishDetectedLanguage = detectedLanguage(textEN) // => English
let spanishDetectedLanguage = detectedLanguage(textES) // => Spanish
let arabicDetectedLanguage = detectedLanguage(textAR) // => Arabic
let germanDetectedLanguage = detectedLanguage(textDE) // => German
有沒有簡單的方法來實現它?
您可以通過使用NLlanguageRecognizer來實現它,如下所示:
import NaturalLanguage
func detectedLanguage(for string: String) -> String? {
let recognizer = NLLanguageRecognizer()
recognizer.processString(string)
guard let languageCode = recognizer.dominantLanguage?.rawValue else { return nil }
let detectedLanguage = Locale.current.localizedString(forIdentifier: languageCode)
return detectedLanguage
}
您可以通過使用NSLinguisticTagger來實現它,如下所示:
func detectedLanguage<T: StringProtocol>(for string: T) -> String? {
let recognizer = NLLanguageRecognizer()
recognizer.processString(String(string))
guard let languageCode = recognizer.dominantLanguage?.rawValue else { return nil }
let detectedLanguage = Locale.current.localizedString(forIdentifier: languageCode)
return detectedLanguage
}
首先,你應該知道你問的是什么主要與 自然語言處理(NLP)世界有關。
由於 NLP 不僅僅是文本語言檢測,因此答案的其余部分將不包含特定的 NLP 信息。
顯然,實現這樣的功能並不是那么容易,尤其是當開始關心過程的細節時,例如拆分成句子甚至拆分成單詞,然后識別名稱和標點符號等......我敢打賭你會想到“什么一個痛苦的過程!我自己做這件事甚至不合邏輯”; 幸運的是,iOS確實支持 NLP(實際上,NLP API 可用於所有 Apple 平台,不僅僅是 iOS),使您的目標易於實現。 您將使用的核心組件是NSLinguisticTagger
:
分析自然語言文本以標記詞性和詞匯類別、識別名稱、執行詞形還原以及確定語言和腳本。
NSLinguisticTagger
為各種自然語言處理功能提供了統一的接口,並支持許多不同的語言和腳本。 您可以使用此類將自然語言文本分割為段落、句子或單詞,並標記有關這些段的信息,例如詞性、詞匯類、引理、腳本和語言。
如類文檔中所述,您正在尋找的方法 - 在確定主導語言和正字法部分下 - 是dominantLanguage(for:)
:
返回指定字符串的主要語言。
.
.
返回值
BCP-47標簽標識字符串的主要語言,如果無法確定特定語言,則使用標簽“und”。
您可能會注意到NSLinguisticTagger
是從 iOS 5 NSLinguisticTagger
就存在的。 但是,僅在 iOS 11 及更高版本上支持dominantLanguage(for:)
方法,這是因為它是在Core ML Framework之上開發的:
. . .
Core ML 是特定領域框架和功能的基礎。 Core ML 支持用於圖像分析的 Vision、用於自然語言處理的Foundation (例如
NSLinguisticTagger
類)和用於評估學習決策樹的 GameplayKit。 Core ML 本身建立在 Accelerate 和 BNNS 等低級原語以及 Metal Performance Shaders 之上。
基於通過傳遞“The quick brown fox jumps over the lazy dog”調用dominantLanguage(for:)
的返回值:
NSLinguisticTagger.dominantLanguage(for: "The quick brown fox jumps over the lazy dog")
將是“en”可選字符串。 但是,到目前為止,這不是所需的輸出,而是期望得到“英語”! 好吧,這正是您應該通過從Locale Structure 調用localizedString(forLanguageCode:)
方法並傳遞獲得的語言代碼來獲得的:
Locale.current.localizedString(forIdentifier: "en") // English
如“快速回答”代碼片段中所述,該函數將是:
func detectedLanguage<T: StringProtocol>(_ forString: T) -> String? {
guard let languageCode = NSLinguisticTagger.dominantLanguage(for: String(forString)) else {
return nil
}
let detectedLanguage = Locale.current.localizedString(forIdentifier: languageCode)
return detectedLanguage
}
輸出:
它會如預期的那樣:
let englishDetectedLanguage = detectedLanguage(textEN) // => English
let spanishDetectedLanguage = detectedLanguage(textES) // => Spanish
let arabicDetectedLanguage = detectedLanguage(textAR) // => Arabic
let germanDetectedLanguage = detectedLanguage(textDE) // => German
請注意:
仍然存在無法獲取給定字符串的語言名稱的情況,例如:
let textUND = "SdsOE"
let undefinedDetectedLanguage = detectedLanguage(textUND) // => Unknown language
或者它甚至可能nil
:
let rubbish = "000747322"
let rubbishDetectedLanguage = detectedLanguage(rubbish) // => nil
仍然發現提供有用的輸出是一個不錯的結果......
關於 NSLinguisticTagger:
雖然我不會深入研究NSLinguisticTagger
用法,但我想指出,它存在一些非常酷的功能,而不僅僅是簡單地檢測給定文本的語言; 作為一個非常簡單的例子:在枚舉標簽時使用引理在使用信息檢索時非常有用,因為您將能夠識別“駕駛”這個詞通過“駕駛”這個詞。
蘋果視頻會議:
NSLinguisticTagger
如何工作的更多信息: 自然語言處理和您的應用程序。此外,為了熟悉 CoreML:
您可以使用 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
我用像hello
這樣的短輸入文本嘗試了NSLinguisticTagger
,它總是識別為意大利語。 幸運的是,Apple 最近在 iOS 12 上添加了NLLanguageRecognizer ,而且似乎更准確: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)
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.