首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >NSCharacterSet.characterIsMember()与Swift的字符类型

NSCharacterSet.characterIsMember()与Swift的字符类型
EN

Stack Overflow用户
提问于 2014-12-29 23:27:24
回答 5查看 9.4K关注 0票数 33

假设您有一个Swift的Character类型的实例,并且希望确定它是否是一个NSCharacterSet的成员。NSCharacterSetcharacterIsMember方法需要一个unichar,所以我们需要从Characterunichar

我能想出的唯一解决方案是:c是我的Character

代码语言:javascript
复制
let u: unichar = ("\(c)" as NSString).characterAtIndex(0)
if characterSet.characterIsMember(u) {
    dude.abide()
}

我看了看Character,但是没有什么东西可以跳出来作为从它到unichar的方法。这可能是因为Characterunichar更通用,所以直接转换是不安全的,但我只是猜测。

如果我要迭代整个字符串,我会这样做:

代码语言:javascript
复制
let s = myString as NSString
for i in 0..<countElements(myString) {
    let u = s.characterAtIndex(i)
    if characterSet.characterIsMember(u) {
        dude.abide()
    }
}

(警告:以上是伪代码,从未有人运行过。)但这不是我想要的。

EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2014-12-30 00:20:38

我的理解是,unicharUInt16的一个类型。unichar只是一个数字。

我认为您面临的问题是Swift中的Character可以由多个unicode“字符”组成。因此,它不能转换为单个unichar值,因为它可能由两个独角兽组成。您可以通过将Character转换为字符串并使用utf16属性将其分解为单独的unichar值,如下所示:

代码语言:javascript
复制
let c: Character = "a"
let s = String(c)
var codeUnits = [unichar]()
for codeUnit in s.utf16 {
    codeUnits.append(codeUnit)
}

这将产生一个数组-- codeUnits -- unichar值。

编辑:最初的代码应该是for codeUnit in s,而它应该是for codeUnit in s.utf16

您可以整理并测试每个单独的unichar值是否位于这样的字符集中:

代码语言:javascript
复制
let char: Character = "\u{63}\u{20dd}" // This is a 'c' inside of an enclosing circle
for codeUnit in String(char).utf16 {
    if NSCharacterSet(charactersInString: "c").characterIsMember(codeUnit) {
        dude.abide()
    } // dude will abide() for codeUnits[0] = "c", but not for codeUnits[1] = 0x20dd (the enclosing circle)
}

或者,如果您只对第一个(而且通常也只是) unichar值感兴趣:

代码语言:javascript
复制
if NSCharacterSet(charactersInString: "c").characterIsMember(String(char).utf16[0]) {
    dude.abide()
}

或者,将它包装在一个函数中:

代码语言:javascript
复制
func isChar(char: Character, inSet set: NSCharacterSet) -> Bool {
    return set.characterIsMember(String(char).utf16[0])
}

let xSet = NSCharacterSet(charactersInString: "x")
isChar("x", inSet: xSet)  // This returns true
isChar("y", inSet: xSet)  // This returns false

现在,对一个组合字符中的所有unichar值进行函数检查-这样,如果您有一个组合字符,则只有在基本字符和组合字符都存在时,函数才会返回true:

代码语言:javascript
复制
func isChar(char: Character, inSet set: NSCharacterSet) -> Bool {
    var found = true
    for ch in String(char).utf16 {
        if !set.characterIsMember(ch) { found = false }
    }
    return found
}

let acuteA: Character = "\u{e1}"                   // An "a" with an accent
let acuteAComposed: Character = "\u{61}\u{301}"    // Also an "a" with an accent

// A character set that includes both the composed and uncomposed unichar values
let charSet = NSCharacterSet(charactersInString: "\u{61}\u{301}\u{e1}")

isChar(acuteA, inSet: charSet)           // returns true
isChar(acuteAComposed, inSet: charSet)   // returns true (both unichar values were matched

最后一个版本很重要。如果您的Character是一个组合字符,您必须检查字符集中是否存在基本字符("a")和组合字符(尖锐重音),否则您将得到假阳性。

票数 22
EN

Stack Overflow用户

发布于 2014-12-30 00:48:35

我会把这个字符当作字符串,让Cocoa来做所有的工作:

代码语言:javascript
复制
func charset(cset:NSCharacterSet, containsCharacter c:Character) -> Bool {
    let s = String(c)
    let ix = s.startIndex
    let ix2 = s.endIndex
    let result = s.rangeOfCharacterFromSet(cset, options: nil, range: ix..<ix2)
    return result != nil
}

下面是如何使用它:

代码语言:javascript
复制
let cset = NSCharacterSet.lowercaseLetterCharacterSet()
let c : Character = "c"
let ok = charset(cset, containsCharacter:c) // true
票数 12
EN

Stack Overflow用户

发布于 2017-05-11 14:32:21

用一个班轮来做所有的事情:

代码语言:javascript
复制
validCharacterSet.contains(String(char).unicodeScalars.first!)

(Swift 3)

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/27697508

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档