了解Swift的CharacterSet
tldr:单击 此处 查看 CharacterSet.decimalDigits
所有 CharacterSet.decimalDigits
您是否曾经需要检查过字符串是否仅由数字组成? 标点符号或非字母数字字符的存在如何? 一个人可以使用多种方法,从Formatter
类之一到NSScanner
甚至是NSPredicate
,但是您发现的最可能的代码片段涉及到使用反向的CharacterSet
。
简而言之, CharacterSet
是一个由Objective-C桥接的Swift类,它代表一组Unicode字符。 它的Objective-C对应物NSCharacterSet
本身是免费的,与Core Foundation的CFCharacterSet
桥接。 CFCharacterSet
用C编写,相当古老,至少可以追溯到Mac CFCharacterSet
的主要思想是提供一种支持Unicode的数据结构,以帮助有效地搜索Unicode字符串。 NSString
和NSScanner
内部使用NSCharacterSet
进行字符串搜索操作。
可以将CharacterSet
初始化为空集,也可以将其初始化为字符串,字节或文件内容中存在的一组字符。 它带有许多方便的预定义集合(例如URL查询片段中允许的字符或字母数字字符),甚至还允许集合代数(例如并集,交集和异或)。
使用CharacterSet
的预定义集合之一感觉很方便:
请注意,四个8位和两个16位都加起来为32位。 这完全是设计使然:UTF32是固定宽度格式,UTF8和UTF16可以轻松装入其中,而无需进行任何额外工作。 所有UTF32字符都包含32位,即使不是必需的。 这使格式无效,但是有一个好处 :它非常适合搜索,因为您可以遍历第32位以获得下一个字符,而不用解码每个字节来解码该字符的代码点宽度。 这正是NSCharacterSet.characterIsMember(UTF8 or UTF16 or UTF32)
内部调用仅接受UTF32字符的longCharacterIsMember(UTF32)
的原因NSCharacterSet.characterIsMember(UTF8 or UTF16 or UTF32)
在CharacterSet
搜索字符成员资格的最佳方法是获取该CharacterSet
的UTF32代码点,并将其传递给NSCharacterSet
的longCharacterIsMember()
。 看起来像这样:
以下是将字符的代码点值转换为UTF8二进制文件的方法:在上表中的所有x
s中填充字符的二进制值。
要确定需要多少字节,请考虑二进制字符编码的长度。 1字节的UTF8仅可容纳7位(表中仅7 x
s)。 一个2字节的UTF8可以容纳11位。 3字节可容纳16位,而4字节UTF8可容纳21位。
对于“€”字符(U + 20AC 10 0000 1010 1100
),我们至少需要14位,这意味着它将需要3个字节的结构,可以容纳12至16位。 填充到UTF8结构中的二进制数字如下所示: 1110 0010 10 000010 10 101100
(代码点为bold
)。
请注意,如果您删除了非粗体的二进制数字,您将获得“€”字符的原始二进制!
3字节长的UTF8字符中的第一个字节始终以1110
开头。 这就是UTF8解码器如何知道后面的字节数属于数据流中相同字符的方式。
³参见CFCharacterSet.c的第1655行
⁴我不建议在任何生产应用程序或任何应用程序中使用此代码。 提供的NSCharacterSet
扩展名仅用于教育目的。 代码很慢,并且一些预定义的集合很大 (例如, .alphanumerics
集合包含24,146个字符)。
⁵再一次,我不建议在生产环境中使用NSCharacterSet
扩展。