2016-01-22 165 views
-2

如何获取UTF-8编码形式的字符串长度(不是字节数)(PHP的mb_strlen(.., 'UTF-8')等效项)?获取UTF8中字符串的长度

我试过string.characters.count,但它不会像表情符号那样为特定字符返回正确的长度。

实施例:

let s = "✌️" 
print(s.characters.count) // prints 2, but should print 3. 
+2

您能否给一些输入/输出组合,如“ABC” - > 3,“someUtf-8String” - > 123对验证我们的解决方案!? – luk2302

+0

您可以使用string.utf8.count获得UTF-8计数。您可以使用Array(string.utf8)来获取UTF-8代码单元阵列。 –

+0

@ luk2302增加了一个例子。 – Code

回答

6

可以与.utf8属性访问字符串的UTF-8编码。使用上count得到字符串中的UTF-8编码单元的数量:

let string = "\u{1f603}" // One of the smiley face emojis... 

print(string.utf8.count) // prints "4" 

根据您编辑的问题,什么你可能寻找的是用来串编码UnicodeScalar S上的号码。您访问与unicodeScalars属性:

let s = "✌️" 
print(s.unicodeScalars.count) // prints 3 

大家的原因是混淆是因为你原来的问题要求在其UTF-8编码格式的字符串的长度。您实际需要的答案与UTF-8编码形式的字符串长度无关。

我认为你对Unicode“扩展字形群集”,Unicode代码点和可用于编码Unicode代码点的各种编码(如UTF-8)之间的区别感到困惑。

Swift中的Character表示Unicode称之为“扩展字形群集”。也就是说,即使它是由多个Unicode代码点组成,它也是一个单一的可视化字符。

Unicode代码点是一个给定32位值的单个语言符号。两个或多个Unicode代码点可以组合在一起创建一个Character。在Swift中,Unicode代码点由UnicodeScalar类型表示。

当需要存储一个字符串,或通过互联网发送它,或者将其转换为以字节表示的数据时,您必须决定如何对其进行编码。有各种编码,最常见的可能是UTF-8,它将字符串编码为一系列UInt8值。

这只是三个概念之间差异的简短片段。这实际上是一个非常有趣的主题,如果你谷歌的一些条款,你会发现更多的好消息。

+0

我认为你误解了我的问题。我用一个例子编辑过。 – Code

+1

您问过如何获取UTF-8编码形式的字符串长度。这与用于对其进行编码的字节数相同。如果这不是你所问的,那么请编辑你的问题。 –

+0

我编辑了我的答案。 –

3
let str = "ačŘ" 
print("str has \(str.characters.count) characters") // 3 
print("and \(str.utf8.count) bytes as encoded in UTF-8") // 5 

更新(根据您的笔记)的字符

s.characters.forEach { (c) ->() in 
    let str = String(c) 
    print(str.utf8.map{$0}, "which represents character: ", c) 
    str.unicodeScalars.forEach({ (u) ->() in 
     print("composed from unicode scalar(s): ", u.debugDescription) 
    }) 
} 
/* 
[226, 156, 140] which represents character: ✌ 
composed from unicode scalar(s): "\u{270C}" 
[240, 159, 143, 191, 239, 184, 143] which represents character: ️ 
composed from unicode scalar(s): "\u{0001F3FF}" 
composed from unicode scalar(s): "\u{FE0F}" 
*/ 

Unicode中的每个字符可以由一个或多个Unicode标量来表示

let s = "✌️" 

let arr:[UInt8] = [226, 156, 140, 240, 159, 143, 191, 239, 184, 143] 
var arrCchar = arr.map { (uint8) -> Int8 in 
    Int8(bitPattern: uint8) 
} 
arrCchar += [0] // to be null terminated 

let str = String.fromCString(&arrCchar) 
print(str) // Optional("✌️") 
s == str // TRUE !!!! 

。 unicode标量是一个字符或修饰符的唯一21位数字(和名称),例如LOWERCASE LATIN LETTER A(“a”)的U + 0061或FRONT-FACING BABY CHICK的U + 1F425(“\ U0001f425 “)。 将Unicode字符串写入文本文件或其他存储器时,这些unicode标量将以Unicode定义的几种格式之一进行编码。每种格式都将字符串编码为称为代码单元的小块。这些格式包括UTF-8格式(将字符串编码为8位代码单元)和UTF-16格式(将字符串编码为16位代码单元)。

//从苹果开发者迅速编程指南复制

+0

我认为你误解了我的问题。我用一个例子编辑过。 – Code

+0

let s =“✌️”; print(s.characters.count)// 2 ???至少在我的电脑上。试试s.characters.forEach {print($ 0)}。顺便说一下你的s有10个字节,如果编码为UTF-8 – user3441734

+0

我不明白你在说什么。我知道它是10个字节。 '.characters.count'打印2,但我想要的值是3. – Code