Swift 5 如何判断字符串是否以字母开头?
How to Check if String begins with Alphabet Letter in Swift 5?
问题: 我目前正在尝试 Sort a List in SwiftUI
根据 Items First Character
。我还想为所有项目实施 Section
,其中 doesn't begin
带有 Character of the Alphabet
(Numbers, Special Chars).
到目前为止我的代码:
let nonAlphabetItems = items.filter { [=11=].name.uppercased() != /* beginns with A - Z */ }
是否有人对此问题有解决方案。当然我可以做一个巨大的循环构造,但是我希望有一个更优雅的方法。
感谢您的帮助。
您可以通过以下方式使用 NSCharacterSet :
let phrase = "Test case"
let range = phrase.rangeOfCharacter(from: characterSet)
// range will be nil if no letters is found
if let test = range {
println("letters found")
}
else {
println("letters not found")
}```
您可以检查字符串范围 "A"..."Z"
是否包含您姓名的第一个字母 属性:
struct Item {
let name: String
}
let items: [Item] = [.init(name: "Def"),.init(name: "Ghi"),.init(name: "123"),.init(name: "Abc")]
let nonAlphabetItems = items.filter { !("A"..."Z" ~= ([=11=].name.first?.uppercased() ?? "#")) }
nonAlphabetItems // [{name "123"}]
扩展这个主题我们可以扩展 Character
添加一个 isAsciiLetter
属性:
extension Character {
var isAsciiLetter: Bool { "A"..."Z" ~= self || "a"..."z" ~= self }
}
这将允许扩展 StringProtocol
以检查字符串是否以 ascii 字母开头:
extension StringProtocol {
var startsWithAsciiLetter: Bool { first?.isAsciiLetter == true }
}
并且只是一个否定布尔值的助手 属性:
extension Bool {
var negated: Bool { !self }
}
现在我们可以按如下方式过滤项目集合:
let nonAlphabetItems = items.filter(\.name.startsWithAsciiLetter.negated) // [{name "123"}]
可以处理ascii值
extension String {
var fisrtCharacterIsAlphabet: Bool {
guard let firstChar = self.first else { return false }
let unicode = String(firstChar).unicodeScalars
let ascii = Int(unicode[unicode.startIndex].value)
return (ascii >= 65 && ascii <= 90) || (ascii >= 97 && ascii <= 122)
}
}
var isAlphabet = "Hello".fisrtCharacterIsAlphabet
Character
类型为此有一个 属性:
let x: Character = "x"
x.isLetter // true for letters, false for punctuation, numbers, whitespace, ...
请注意,这将包括来自其他字母表(希腊文、西里尔文、中文...)的字符。
由于String
是Sequence
,Element
等于Character
,我们可以使用.first
属性得到第一个字符
有了这个,您可以过滤您的项目:
let filtered = items.filter { [=11=].name.first?.isLetter ?? false }
您可以通过这个简单的 String
扩展来完成此操作
extension StringProtocol {
var isFirstCharacterAlp: Bool {
first?.isASCII == true && first?.isLetter == true
}
}
用法:
print ("H1".isFirstCharacterAlp)
print ("ابراهيم1".isFirstCharacterAlp)
输出
true
false
编码愉快!
Reference
如果您偶尔需要一个过滤器,您可以简单地编写一个结合标准谓词 isLetter
and isASCII
的条件,这些谓词已经为 Character
定义。就这么简单:
let items = [ "Abc", "01bc", "Ça va", "", " ", ""]
let nonAlphabetItems = items.filter { [=10=].isEmpty || ![=10=].first!.isASCII || ![=10=].first!.isLetter }
print (nonAlphabetItems) // -> Output: ["01bc", "Ça va", "", " ", ""]
如果字符串不为空,则肯定有第一个字符[=14=].first!
。使用 isLetter
很诱人,但它似乎适用于许多本地字母表中的许多字符,例如古董 Egyptian hieroglyphs like ""
or the French alphabet with "Ç"
and accented characters. This is why you need to restrict it to ASCII letters, to limit yourself to the roman alphabet.
问题: 我目前正在尝试 Sort a List in SwiftUI
根据 Items First Character
。我还想为所有项目实施 Section
,其中 doesn't begin
带有 Character of the Alphabet
(Numbers, Special Chars).
到目前为止我的代码:
let nonAlphabetItems = items.filter { [=11=].name.uppercased() != /* beginns with A - Z */ }
是否有人对此问题有解决方案。当然我可以做一个巨大的循环构造,但是我希望有一个更优雅的方法。
感谢您的帮助。
您可以通过以下方式使用 NSCharacterSet :
let phrase = "Test case"
let range = phrase.rangeOfCharacter(from: characterSet)
// range will be nil if no letters is found
if let test = range {
println("letters found")
}
else {
println("letters not found")
}```
您可以检查字符串范围 "A"..."Z"
是否包含您姓名的第一个字母 属性:
struct Item {
let name: String
}
let items: [Item] = [.init(name: "Def"),.init(name: "Ghi"),.init(name: "123"),.init(name: "Abc")]
let nonAlphabetItems = items.filter { !("A"..."Z" ~= ([=11=].name.first?.uppercased() ?? "#")) }
nonAlphabetItems // [{name "123"}]
扩展这个主题我们可以扩展 Character
添加一个 isAsciiLetter
属性:
extension Character {
var isAsciiLetter: Bool { "A"..."Z" ~= self || "a"..."z" ~= self }
}
这将允许扩展 StringProtocol
以检查字符串是否以 ascii 字母开头:
extension StringProtocol {
var startsWithAsciiLetter: Bool { first?.isAsciiLetter == true }
}
并且只是一个否定布尔值的助手 属性:
extension Bool {
var negated: Bool { !self }
}
现在我们可以按如下方式过滤项目集合:
let nonAlphabetItems = items.filter(\.name.startsWithAsciiLetter.negated) // [{name "123"}]
可以处理ascii值
extension String {
var fisrtCharacterIsAlphabet: Bool {
guard let firstChar = self.first else { return false }
let unicode = String(firstChar).unicodeScalars
let ascii = Int(unicode[unicode.startIndex].value)
return (ascii >= 65 && ascii <= 90) || (ascii >= 97 && ascii <= 122)
}
}
var isAlphabet = "Hello".fisrtCharacterIsAlphabet
Character
类型为此有一个 属性:
let x: Character = "x"
x.isLetter // true for letters, false for punctuation, numbers, whitespace, ...
请注意,这将包括来自其他字母表(希腊文、西里尔文、中文...)的字符。
由于String
是Sequence
,Element
等于Character
,我们可以使用.first
属性得到第一个字符
有了这个,您可以过滤您的项目:
let filtered = items.filter { [=11=].name.first?.isLetter ?? false }
您可以通过这个简单的 String
扩展来完成此操作
extension StringProtocol {
var isFirstCharacterAlp: Bool {
first?.isASCII == true && first?.isLetter == true
}
}
用法:
print ("H1".isFirstCharacterAlp)
print ("ابراهيم1".isFirstCharacterAlp)
输出
true
false
编码愉快!
Reference
如果您偶尔需要一个过滤器,您可以简单地编写一个结合标准谓词 isLetter
and isASCII
的条件,这些谓词已经为 Character
定义。就这么简单:
let items = [ "Abc", "01bc", "Ça va", "", " ", ""]
let nonAlphabetItems = items.filter { [=10=].isEmpty || ![=10=].first!.isASCII || ![=10=].first!.isLetter }
print (nonAlphabetItems) // -> Output: ["01bc", "Ça va", "", " ", ""]
如果字符串不为空,则肯定有第一个字符[=14=].first!
。使用 isLetter
很诱人,但它似乎适用于许多本地字母表中的许多字符,例如古董 Egyptian hieroglyphs like ""
or the French alphabet with "Ç"
and accented characters. This is why you need to restrict it to ASCII letters, to limit yourself to the roman alphabet.