在Swift中如何检查一个字符串是否包含中文?

10

我想知道如何在Swift中检查字符串是否包含中文?

例如,我想检查以下字符串中是否有中文:

var myString = "Hi! 大家好!It's contains Chinese!"

谢谢!

5个回答

15

这个答案 可以很容易地从Ruby转换成Swift(现在已更新为Swift 3):如何确定字符是否为中文字符

extension String {
    var containsChineseCharacters: Bool {
        return self.range(of: "\\p{Han}", options: .regularExpression) != nil
    }
}

if myString.containsChineseCharacters {
    print("Contains Chinese")
}

在正则表达式中,"\p{Han}" 匹配所有拥有“Han” Unicode属性的字符,据我所知,这些字符来自于CJK语言。

有关编程的内容,请将以下文本从英语翻译成中文。请仅返回翻译后的文本:是否有任何方式可以只获取中文单词?谢谢! - He Yifei 何一非
@Arefly:很遗憾,我不是中文专家,我“盲目地”翻译了Ruby代码 :) 还有“片假名”和“平假名”属性,但我不知道它们是否有用。 - Martin R
@Arefly:如果需要更精细的控制,Airspeed Velocity的回答可能更适合,因为您可以根据需要使用Unicode范围调整表格,例如“仅限中文字符”。 - Martin R

5

查看其他语言(例如Ruby的这个被接受的答案)中如何实现此操作的问题,似乎通常的技术是确定字符串中的每个字符是否属于CJK范围。可以使用以下代码将Ruby答案适应于Swift字符串:

extension String {
    var containsChineseCharacters: Bool {
        return self.unicodeScalars.contains { scalar in
            let cjkRanges: [ClosedInterval<UInt32>] = [
                0x4E00...0x9FFF,   // main block
                0x3400...0x4DBF,   // extended block A
                0x20000...0x2A6DF, // extended block B
                0x2A700...0x2B73F, // extended block C
            ]
            return cjkRanges.contains { $0.contains(scalar.value) }
        }
    }
}

// true:
"Hi! 大家好!It's contains Chinese!".containsChineseCharacters
// false:
"Hello, world!".containsChineseCharacters

这些范围可能已经存在于Foundation中,而不是手动硬编码它们。

上述内容适用于Swift 2.0,在较早的版本中,您需要使用免费的contains函数而不是协议扩展(两次):

extension String {
    var containsChineseCharacters: Bool {
        return contains(self.unicodeScalars) {
          // older version of compiler seems to need extra help with type inference 
          (scalar: UnicodeScalar)->Bool in
            let cjkRanges: [ClosedInterval<UInt32>] = [
                0x4E00...0x9FFF,   // main block
                0x3400...0x4DBF,   // extended block A
                0x20000...0x2A6DF, // extended block B
                0x2A700...0x2B73F, // extended block C
            ]
            return contains(cjkRanges) { $0.contains(scalar.value) }
        }
    }
}

错误:String.UnicodeScalarView 没有名为 contains 的成员? - He Yifei 何一非
啊,抱歉,这是Swift 2.0的版本,让我为1.2版本提供一个。 - Airspeed Velocity

3

接受的答案只能找到字符串是否包含中文字符,我为自己的情况创建了一个适合的解决方案:

enum ChineseRange {
    case notFound, contain, all
}

extension String {
    var findChineseCharacters: ChineseRange {
        guard let a = self.range(of: "\\p{Han}*\\p{Han}", options: .regularExpression) else {
            return .notFound
        }
        var result: ChineseRange
        switch a {
        case nil:
            result = .notFound
        case self.startIndex..<self.endIndex:
            result = .all
        default:
            result = .contain
        }
        return result
    }
}

if "你好".findChineseCharacters == .all {
    print("All Chinese")
}

if "Chinese".findChineseCharacters == .notFound {
    print("Not found Chinese")
}

if "Chinese你好".findChineseCharacters == .contain {
    print("Contains Chinese")
}

这里有一个代码片段:https://gist.github.com/williamhqs/6899691b5a26272550578601bee17f1a

该代码片段包含了一些关于IT技术的信息。如果您需要帮助,请告诉我。

正是我所需要的。干杯! - NSAdi
"你 好".findChineseCharacters 应该返回 .all - William Hu

2

尝试在Swift 2中使用以下代码:

var myString = "Hi! 大家好!It's contains Chinese!"

var a = false

for c in myString.characters {
    let cs = String(c)
    a = a || (cs != cs.stringByApplyingTransform(NSStringTransformMandarinToLatin, reverse: false))
}
print("\(myString) contains Chinese characters = \(a)")

0

我创建了一个Swift 3字符串扩展,用于检查一个字符串包含多少个中文字符。类似于Airspeed Velocity的代码,但更全面。检查各种Unicode范围以确定字符是否为中文。请参阅Unicode标准规范第18.1节下表中列出的中文字符范围:http://www.unicode.org/versions/Unicode9.0.0/ch18.pdf

可以在GitHub上找到该字符串扩展程序:https://github.com/niklasberglund/String-chinese.swift

使用示例:

let myString = "Hi! 大家好!It contains Chinese!"
let chinesePercentage = myString.chinesePercentage()
let chineseCharacterCount = myString.chineseCharactersCount()
print("String contains \(chinesePercentage) percent Chinese. That's \(chineseCharacterCount) characters.")

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接