检查字符串是拉丁语还是西里尔语

时间:2016-08-02 13:54:48

标签: ios swift

是否有某种方法可以检查是否有拉丁语或西里尔字母?我已经尝试过localizedCompare字符串方法,但它没有给我所需的结果。

7 个答案:

答案 0 :(得分:2)

您应该获取所有unicode字符,并根据unicode值检测是否包含西里尔字符或拉丁字符。这段代码不是complet,你可以完成它。

let a : String = "ӿ" //unicode value = 04FF
let scalars = a.unicodeScalars

//get unicode value of first char:
let unicodeValue = scalars[scalars.startIndex].value  //print 1279, correspondant to 04FF.

在此处检查所有unicode值(以hexa为单位)。 http://jrgraphix.net/r/Unicode/0400-04FF

根据该网站,西里尔值为0400 - > 04FF(1024 - > 1279)

这是西里尔文检查的代码:

var isCyrillic = true
for (index, unicode) in scalars.enumerate() {
    if (unicode.value < 1024 || unicode.value > 1279) {
        print("not a cyrillic text")
        print(unicode.value)
        isCyrillic = false
        break
    }
}

答案 1 :(得分:1)

这样的事情怎么样?

extension String {
    var isLatin: Bool {
        let upper = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
        let lower = "abcdefghijklmnopqrstuvwxyz"

        for c in self.characters.map({ String($0) }) {
            if !upper.containsString(c) && !lower.containsString(c) {
                return false
            }
        }

        return true
    }

    var isCyrillic: Bool {
        let upper = "АБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЬЮЯ"
        let lower = "абвгдежзийклмнопрстуфхцчшщьюя"

        for c in self.characters.map({ String($0) }) {
            if !upper.containsString(c) && !lower.containsString(c) {
                return false
            }
        }

        return true
    }

    var isBothLatinAndCyrillic: Bool {
        return self.isLatin && self.isCyrillic
    }
}

<强>用法

let s = "Hello"
if s.isLatin && !s.isBothLatinAndCyrillic {
    // String is latin
} else if s.isCyrillic && !s.isBothLatinAndCyrillic {
    // String is cyrillic
} else if s.isBothLatinAndCyrillic {
    // String can be either latin or cyrillic
} else {
    // String is not latin nor cyrillic
}

考虑到有些情况下给定的字符串可以是两者,例如字符串:

let s = "A"

可以是拉丁语或西里尔语。所以这就是“两者兼有”的原因。

它也可能都不是:

let s = "*"

答案 2 :(得分:1)

令人惊讶的是,你的问题没有简单的答案。拉丁字母包含的不仅仅是A - Z.法语和古代形式的重音字符都是德语等。我不知道西里尔字母,所以我会不管它。最重要的是,你必须处理:标点符号(.,?"()等)和空格,表情符号,箭头,dingbats ......这些都是语言中立的。根据您的要求,复杂性可能会迅速升级。

您接受的答案至少可以说:"hello world".isLatin == false,因为它不处理空格。

访问网站like this one,了解哪些范围包含哪种语言的字符,并使用以下代码进行播放。这不是一个完整的答案,但意味着让你开始:

let neutralRanges  = [0x20...0x40]
let latinRanges    = [0x41...0x5A, 0x61...0x7A, 0xC0...0xFF, 0x100...0x17F]
let cyrillicRanges = [0x400...0x4FF, 0x500...0x52F]

func scalar(scalar: UnicodeScalar, isInRanges ranges: [Range<Int>]) -> Bool {
    for r in ranges {
        if r ~= Int(scalar.value) {
            return true
        }
    }

    return false
}

let str = "Hello world"
var isLatin = true
var isCyrillic = true

for s in "Hello world".unicodeScalars {
    if scalar(s, isInRanges: neutralRanges) {
        continue
    }
    else if !scalar(s, isInRanges: latinRanges) {
        isLatin = false
    }
    else if !scalar(s, isInRanges: cyrillicRanges) {
        isCyrillic = false
    }
}

print(isLatin)
print(isCyrillic)

答案 3 :(得分:0)

斯威夫特3:     波斯语和阿拉伯语

extension String {

    var isFarsi: Bool {

        //Remove extra spaces from the first and last word
        let value = self.trimmingCharacters(in: CharacterSet.whitespacesAndNewlines)

        if value == "" {
            return false
        }

        let farsiLetters = "آ ا ب پ ت ث ج چ ح خ د ذ ر ز ژ س ش ص ض ط ظ ع غ ف ق ک گ ل م ی ن و ه"
        let arabicLetters = " ء ا أ إ ء ؤ ئـ ئ آ اً ة ا ب ت ث ج ‌ ح خ د ذ ر ز س ‌ ش ص ض ط ظ ع غ ف ق ك ل م ن ه و ي"
        for c in value.characters.map({ String($0) }) {
            if !farsiLetters.contains(c) && !arabicLetters.contains(c) {
                return false
            }
        }

        return true
    }      

}

答案 4 :(得分:0)

一些评论引用了另一篇文章,该文章展示了一种使用NSLinguisticTagger(How to detect text (string) language in iOS?)确定String语言的相当干净的方法。

NSLinguisticTagger绝对是此处的最佳方法,并且正是为此目的而设计的,但是对我来说,这听起来像是您实际上在询问如何识别String的脚本而不是语言。例如,英语,法语,德语都使用拉丁字母,因此上面的语言示例并未显示出区分拉丁字母和西里尔字母(或其他脚本)的理想方式。

相反,我对String编写了以下扩展名,该扩展名显示了如何识别所提供的String中第一句话的脚本-然后,您可以轻松地对此进行改编/构建,以获取所需的确切用例: / p>

import Foundation // Needed for NSLinguisticTagger

extension String {
    func scriptCode() -> NSLinguisticTag? {
        let linguisticTagger = NSLinguisticTagger(tagSchemes: [.script], options: 0)

        linguisticTagger.string = self

        return iso15924ScriptCode = linguisticTagger.tag(at: 0, unit: .sentence, scheme: .script, tokenRange: nil)
    }
}

脚本由四个字母的ISO 15924脚本代码统一描述,例如“ Latn”,这是通过返回的NSLinguisticTag对象获得的。要进行比较,只需检查NSLinguisticTag的原始值,例如:

if yourTestSentence.scriptCode()? == "Latn" || "Cyrl" {
    print("This sentence is in Latin or Cyrillic script")
} else {
    print("Some other script")
}

注意事项:本示例仅检查您提供的任何字符串的第一句。我还没有测试如果该句子是混合脚本会发生什么情况-最有可能返回的标签为nil。

以下是一些有用的指向Apple文档和Wikipedia的参考链接,以获取更多信息:

答案 5 :(得分:0)

我希望这也有用

 let cyrillicToLatinMap: [Character : String] = [
" ":" ",
"А":"A",
"Б":"B",
"В":"V",
"Г":"G",
"Д":"D",
"Е":"E",
"Ж":"Zh",
"З":"Z",
"И":"I",
"Й":"Y",
"К":"K",
"Л":"L",
"М":"M",
"Н":"N",
"О":"O",
"П":"P",
"Р":"R",
"С":"S",
"Т":"T",
"У":"U",
"Ф":"F",
"Х":"H",
"Ц":"Ts",
"Ч":"Ch",
"Ш":"Sh",
"Щ":"Sht",
"Ю":"Yu",
"Я":"Ya",
"а":"a",
"б":"b",
"в":"v",
"г":"g",
"д":"d",
"е":"e",
"ж":"zh",
"з":"z",
"и":"i",
"й":"y",
"к":"k",
"л":"l",
"м":"m",
"н":"n",
"о":"o",
"п":"p",
"р":"r",
"с":"s",
"т":"t",
"у":"u",
"ф":"f",
"х":"h",
"ц":"ts",
"ч":"ch",
"ш":"sh",
"щ":"sht",
"ь":"y",
"ю":"yu",
"я":"ya",]
  

保加利亚西里尔字母为拉丁语

 class CyrilicToLatinConverter {

public static func getLatin(wordInCyrillic: String) -> String{
    if(wordInCyrillic.isEmpty) {return wordInCyrillic}
    else{
        let characters = Array(wordInCyrillic)
        var wordInLatin: String = ""
        for n in 0...characters.capacity-1 {
            if isCyrillic(characters: characters[n]) {
                wordInLatin+=cyrillicToLatinMap[characters[n]]!
            }
            else{
                return ""
            }
        }
        return wordInLatin
    }
}

public static func isCyrillic(characters: Character) -> Bool {
    var isCyrillic: Bool = true;
    for (key,_) in cyrillicToLatinMap{
        isCyrillic = (key == characters)
        if isCyrillic {
            break
        }
    }
    return isCyrillic
}

答案 6 :(得分:0)

swift 5解决方案

extension String {
    var isLatin: Bool {
        let upper = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
        let lower = "abcdefghijklmnopqrstuvwxyz"
        for c in self.map({String($0)}) where !upper.contains(c) && !lower.contains(c) {
            return false
        }
        return true
    }
}