在 Swift 中不用正则表达式将字符串减少为字母、数字和空格的最简单方法?

hga*_*ale 0 swift

我目前有一个函数,其目的是从字符串中删除所有不是字母、数字或空格的字符。但坦率地说,我厌倦了正则表达式,因为它是一只丑陋的恐龙。我想要一种更快速的方式来处理这个功能。有吗?

func cleanName(_ name: String) -> String {
    let negated = "[^A-Za-z0-9 ]+"
    return name.replacingOccurrences(of: negated, with: "", options: [.regularExpression])
}

let name = "@$%ab_049*"
print(cleanName(name)) // ab049
Run Code Online (Sandbox Code Playgroud)

Leo*_*bus 5

您可以使用 Swift 5 或更高版本的 Character 属性,例如isLetter,isWholeNumberisWhitespace组合和过滤有效字符:

func cleanName(_ name: String) -> String {
    name.filter{ $0.isLetter || $0.isWholeNumber || $0.isWhitespace }
}
Run Code Online (Sandbox Code Playgroud)

另一种选择是使用模式匹配运算符:

func cleanName(_ name: String) -> String {
    name.filter{ "0"..."9" ~= $0 || "A"..."Z" ~= $0 || "a"..."z" ~= $0 || $0 == " " } 
}
Run Code Online (Sandbox Code Playgroud)

注意:注意isLetter不等同于 [A-Za-z]。对于某些特殊字符以及常规字母表,它将返回 true。从文档中,以下字符都是字母:

• “A”(U+0041 拉丁文大写字母A)
• “é”(U+0065 拉丁文小写字母E,U+0301 组合急性口音)
• “?” (U+03F4 希腊大写 THETA 符号)
• “?” (U+0688 阿拉伯字母 DDAL)
• “?” (U+65E5 CJK 统一表意文字-65E5)
• “?” (U+16A8 符文字母 ANSUZ A)


这同样适用于isWholeNumber字符属性。从文档中,以下字符都代表整数:

• “1” (U+0031 DIGIT ONE) => 1
• “?” (U+096B 梵文数字五) => 5
• “?” (U+0E59 泰语数字九) => 9
• “?” (U+4E07 CJK 统一表意文字-4E07) => 10_000


因此,如果您想在您的帖子中获得与正则表达式相同的行为,您可以扩展 Character 并创建您自己的计算属性以仅对 az、AZ 或 0-9 中的字符返回 true:

extension Character {
    var isAlphabet: Bool { "a"..."z" ~= self || "A"..."Z" ~= self }
    var isDigit: Bool { "0"..."9" ~= self }
    var isAlphaNumeric: Bool { isAlphabet || isDigit }
    var isAlphaNumericOrSpace: Bool { isAlphabet || isDigit || self == " " }
} 
Run Code Online (Sandbox Code Playgroud)

您还可以扩展 StringProtocol 并创建一个自定义属性来清理您的字符串:

extension StringProtocol where Self: RangeReplaceableCollection {
    var cleanedUp: Self {
        filter(\.isAlphaNumericOrSpace)
    }
}
Run Code Online (Sandbox Code Playgroud)

用法:

let name = "@$%ab_049*"
name.cleanedUp  // ab049
Run Code Online (Sandbox Code Playgroud)

  • 第一个是如此迅速。 (3认同)