如何从字符串中获取数字字符?我不想转换Int.
var string = "string_1"
var string2 = "string_20_certified"
Run Code Online (Sandbox Code Playgroud)
我的结果必须格式如下:
newString = "1"
newString2 = "20"
Run Code Online (Sandbox Code Playgroud)
dfr*_*fri 11
String西方阿拉伯数字的unicode标量您可以将a 的unicodeScalars视图模式匹配String到给定UnicodeScalar模式(例如,涵盖西方阿拉伯数字).
extension String {
var westernArabicNumeralsOnly: String {
let pattern = UnicodeScalar("0")..."9"
return String(unicodeScalars
.flatMap { pattern ~= $0 ? Character($0) : nil })
}
}
Run Code Online (Sandbox Code Playgroud)
用法示例:
let str1 = "string_1"
let str2 = "string_20_certified"
let str3 = "a_1_b_2_3_c34"
let newStr1 = str1.westernArabicNumeralsOnly
let newStr2 = str2.westernArabicNumeralsOnly
let newStr3 = str3.westernArabicNumeralsOnly
print(newStr1) // 1
print(newStr2) // 20
print(newStr3) // 12334
Run Code Online (Sandbox Code Playgroud)
上面的unicode标量模式匹配方法特别有用,可以将其扩展到匹配几个给定模式中的任何一个,例如描述东方阿拉伯数字的不同变化的模式:
extension String {
var easternArabicNumeralsOnly: String {
let patterns = [UnicodeScalar("\u{0660}")..."\u{0669}", // Eastern Arabic
"\u{06F0}"..."\u{06F9}"] // Perso-Arabic variant
return String(unicodeScalars
.flatMap { uc in patterns.contains{ $0 ~= uc } ? Character(uc) : nil })
}
}
Run Code Online (Sandbox Code Playgroud)
这可以在实践中使用,例如,如果编写表情符号过滤器,因为覆盖表情符号的unicode标量的范围可以容易地添加到patterns上面的东部阿拉伯语示例中的阵列中.
UnicodeScalar模式方法而不是模式Character?CharacterSwift中的A 包含扩展的字形集群,该集群由一个或多个 Unicode标量值组成.这意味着CharacterSwift中的实例在内存中没有固定大小,这意味着对O(1)中的顺序(/连续)存储字符集合中的字符的随机访问将不可用,而是O(n) ).
另一方面,Swift中的Unicode标量存储在固定大小的UTF-32代码单元中,这应该允许O(1)随机访问.现在,我不能完全肯定,如果这是事实,还是为了什么如下的理由:但事实是,如果采用基准上述方法VS等效方法CharacterView(.characters财产)的一些测试String情况下,它非常的明显UnicodeScalar方法比Character方法快; 天真的测试表明,执行时间差异为10-25倍,随着String规模的增长而稳步增长.
了解使用Unicode标量与使用Swift中的字符的限制
然而,现在,使用该UnicodeScalar方法存在缺点; 即当处理不能由单个unicode标量表示的字符时,但是其中一个unicode标量包含在我们想要匹配的模式中.
例如,考虑一个包含四个字符 的字符串"Café".最后一个字符"é"由两个unicode标量表示,"e"并且"\u{301}".如果我们要实现模式匹配,比如说,UnicodeScalar("a")...e上面应用的过滤方法将允许两个unicode标量之一通过.
extension String {
var onlyLowercaseLettersAthroughE: String {
let patterns = [UnicodeScalar("1")..."e"]
return String(unicodeScalars
.flatMap { uc in patterns.contains{ $0 ~= uc } ? Character(uc) : nil })
}
}
let str = "Cafe\u{301}"
print(str) // Café
print(str.onlyLowercaseLettersAthroughE) // Cae
/* possibly we'd want "Ca" or "Caé"
as result here */
Run Code Online (Sandbox Code Playgroud)
在本问答中OP查询的特定用例中,上述问题不是问题,但根据用例,有时更适合使用Character模式匹配UnicodeScalar.
编辑:更新为Swift 4和5
这是一个不需要Foundation的简单方法:
let newstring = string.filter { "0"..."9" ~= $0 }
Run Code Online (Sandbox Code Playgroud)
或借用@dfri的想法进行String扩展:
extension String {
var numbers: String {
return filter { "0"..."9" ~= $0 }
}
}
print("3 little pigs".numbers) // "3"
print("1, 2, and 3".numbers) // "123"
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
6993 次 |
| 最近记录: |