[英]Swift convert 'Character' to 'Unicode.Scalar'
I'm trying to filter non-alphabetical characters out of a String, but running into the issue that CharacterSet
uses Unicode.Scalar
and String consists of Character
.我试图从 String 中过滤出非字母字符,但遇到了
CharacterSet
使用Unicode.Scalar
和 String 由Character
组成的问题。
Xcode gives the error: Xcode 给出了错误:
Cannot convert value of type 'String.Element' (aka 'Character') to specified type 'Unicode.Scalar?'
无法将“String.Element”(又名“Character”)类型的值转换为指定类型“Unicode.Scalar”?
let name = "name"
let allowedCharacters = CharacterSet.alphanumerics
let filteredName = name.filter { (c) -> Bool in
if let s: Unicode.Scalar = c { // cannot convert
return !allowedCharacters.contains(s)
}
return true
}
CharacterSet
has an unfortunate name inherited from Objective C. In reality, it is a set of Unicode.Scalar
s, not of Characters
(“extended grapheme clusters” in Unicode parlance). CharacterSet
有一个不幸的名字,它继承自 Objective C。实际上,它是一组Unicode.Scalar
,而不是Characters
(Unicode 术语中的“扩展Characters
簇”)。 This is necessary, because while there is a finite set of Unicode scalars, there is an infinite number of possible grapheme clusters.这是必要的,因为虽然有一组有限的 Unicode 标量,但有无限数量的可能的字素簇。 For example,
e + ◌̄ + ◌̄ + ◌̄ ...
ad infinitum is still just one cluster.例如,
e + ◌̄ + ◌̄ + ◌̄ ...
ad e + ◌̄ + ◌̄ + ◌̄ ...
仍然只是一个簇。 As such, it is impossible to exhaustively list all possible clusters, and it is often impossible to list the subset of them that has a particular property.因此,不可能详尽地列出所有可能的集群,并且通常不可能列出具有特定属性的它们的子集。 Set operations such as those in the question must use scalars instead (or at least use definitions derived from the component scalars).
问题中的集合操作必须改用标量(或至少使用从组件标量派生的定义)。
In Swift, String
s have a unicodeScalars
property for operating on the string a the scalar level, and the property is directly mutable.在 Swift 中,
String
有一个unicodeScalars
属性,用于在标量级别对字符串进行操作,并且该属性是直接可变的。 That enables you to do things like this:这使您可以执行以下操作:
// Assuming...
var name: String = "..."
// ...then...
name.unicodeScalars.removeAll(where: { !CharacterSet.alphanumerics.contains($0) })
A single Character
can consist of several UnicodeScalar
s, so you need to iterate through all of them and check if they are contained in CharacterSet.alphanumerics
. 一个
Character
可以包含多个UnicodeScalar
,因此您需要遍历所有UnicodeScalar
,并检查它们是否包含在CharacterSet.alphanumerics
。
let allowedCharacters = CharacterSet.alphanumerics
let filteredName = name.filter { (c) -> Bool in
return !c.unicodeScalars.contains(where: { !allowedCharacters.contains($0)})
}
Test input: let name = "asd😊1"
测试输入:
let name = "asd😊1"
Test output: "asd1"
测试输出:
"asd1"
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.