是否有某种方法可以检查是否有拉丁语或西里尔字母?我已经尝试过localizedCompare
字符串方法,但它没有给我所需的结果。
答案 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
}
}