过滤字符串中的非数字

问题描述 投票:0回答:13

仅使用快速代码,我无法弄清楚如何获取“(555) 555-5555”并仅返回数值并获得“5555555555”。我需要删除所有括号、空格和破折号。我能找到的唯一例子是 Objective-C 中的,它们似乎都使用 .trim() 方法。看起来好像 swift 没有这个方法,但它确实有 .stringByTrimmingCharacters 方法,但这似乎只是修剪数据前后的空格。

swift string numbers
13个回答
131
投票

斯威夫特 3 和 4

extension String {
    var digits: String {
        return components(separatedBy: CharacterSet.decimalDigits.inverted)
            .joined()
    }
}

斯威夫特5

你应该可以省略

return

还有: 请阅读@onmyway133 的评论以获取警告


65
投票

将字符串按非数字字符拆分为数字数组,然后将它们连接回字符串:

斯威夫特1:

let stringArray = origString.componentsSeparatedByCharactersInSet(
    NSCharacterSet.decimalDigitCharacterSet().invertedSet)
let newString = NSArray(array: stringArray).componentsJoinedByString("")

斯威夫特2:

let stringArray = origString.componentsSeparatedByCharactersInSet(
    NSCharacterSet.decimalDigitCharacterSet().invertedSet)
let newString = stringArray.joinWithSeparator("")

Swift 3 和 4:

let newString = origString
    .components(separatedBy:CharacterSet.decimalDigits.inverted)
    .joined()

22
投票

我喜欢正则表达式:

var s = "(555) 555-5555"
s = s.stringByReplacingOccurrencesOfString(
    "\\D", withString: "", options: .RegularExpressionSearch, 
    range: s.startIndex..<s.endIndex)

15
投票

在 Swift 4 中,解决方案更好:

import Foundation

let sourceText = "+5 (555) 555-5555"

let allowedCharset = CharacterSet
    .decimalDigits
    .union(CharacterSet(charactersIn: "+"))

let filteredText = String(sourceText.unicodeScalars.filter(allowedCharset.contains))

print(filteredText) // +55555555555

10
投票

这是 @Tapani 的 Swift 2.0 答案,作为一个方便的字符串扩展,(长度属性不是解决方案的一部分,但我将其留在示例中,因为它也很方便):

import Foundation

extension String {

    var length : Int {
        return self.characters.count
    }

    func digitsOnly() -> String{
        let stringArray = self.componentsSeparatedByCharactersInSet(
            NSCharacterSet.decimalDigitCharacterSet().invertedSet)
        let newString = stringArray.joinWithSeparator("")

        return newString
    }

}

用途:

let phone = "(123)-123 - 1234"
print(phone.digitsOnly())

7
投票

我有类似的问题,但我需要保留小数点。我调整了这个的最佳答案:

extension String {

    /// Returns a string with all non-numeric characters removed
    public var numericString: String {
        let characterSet = CharacterSet(charactersIn: "0123456789.").inverted
        return components(separatedBy: characterSet)
            .joined()
    }
}

6
投票

详情

  • Xcode 版本 10.2.1 (10E1001),Swift 5

解决方案

import Foundation

extension String {

    private func filterCharacters(unicodeScalarsFilter closure: (UnicodeScalar) -> Bool) -> String {
        return String(String.UnicodeScalarView(unicodeScalars.filter { closure($0) }))
    }

    private func filterCharacters(definedIn charSets: [CharacterSet], unicodeScalarsFilter: (CharacterSet, UnicodeScalar) -> Bool) -> String {
        if charSets.isEmpty { return self }
        let charSet = charSets.reduce(CharacterSet()) { return $0.union($1) }
        return filterCharacters { unicodeScalarsFilter(charSet, $0) }
    }

    func removeCharacters(charSets: [CharacterSet]) -> String { return filterCharacters(definedIn: charSets) { !$0.contains($1) } }
    func removeCharacters(charSet: CharacterSet) -> String { return removeCharacters(charSets: [charSet]) }

    func onlyCharacters(charSets: [CharacterSet]) -> String { return filterCharacters(definedIn: charSets) { $0.contains($1) } }
    func onlyCharacters(charSet: CharacterSet) -> String { return onlyCharacters(charSets: [charSet]) }
}

使用方法

let string = "23f45gdor#@%#i425v wer 24 1+DWEJwi 3u09ru49w*()9uE2R_)$I#Q)_ U383q04+RFJO{dgnkvlj b`kefl;nwdl qsa`WKFSA,.E"
print("original string:                                 \(string)")
print("only .decimalDigits:                             \(string.onlyCharacters(charSet: .decimalDigits))")
print("only [.lowercaseLetters, .symbols]:              \(string.onlyCharacters(charSets: [.lowercaseLetters, .symbols]))")
print("remove .letters:                                 \(string.removeCharacters(charSet: .letters))")
print("remove [.decimalDigits, .lowercaseLetters]:      \(string.removeCharacters(charSets: [.decimalDigits, .lowercaseLetters]))")

结果

original string:                                 23f45gdor#@%#i425v wer 24 1+DWEJwi 3u09ru49w*()9uE2R_)$I#Q)_ U383q04+RFJO{dgnkvlj b`kefl;nwdl qsa`WKFSA,.E
only .decimalDigits:                             2345425241309499238304
only [.lowercaseLetters, .symbols]:              fgdorivwer+wiuruwu$q+dgnkvljb`keflnwdlqsa`
remove .letters:                                 2345#@%#425  24 1+ 30949*()92_)$#)_ 38304+{ `; `,.
remove [.decimalDigits, .lowercaseLetters]:      #@%#   +DWEJ *()ER_)$I#Q)_ U+RFJO{ `; `WKFSA,.E

(可选)字符串扩展

extension String {
    var onlyDigits: String { return onlyCharacters(charSets: [.decimalDigits]) }
    var onlyLetters: String { return onlyCharacters(charSets: [.letters]) }
}

(可选)字符串扩展使用

let string = "23f45gdor#@%#i425v wer 24 1+DWEJwi 3u09ru49w*()9uE2R_)$I#Q)_ U383q04+RFJO{dgnkvlj b`kefl;nwdl qsa`WKFSA,.E"
print("original string:     \(string)")
print(".onlyDigits:         \(string.onlyDigits)")
print(".onlyLetters:        \(string.onlyLetters)")

(可选)字符串扩展使用结果

original string:     23f45gdor#@%#i425v wer 24 1+DWEJwi 3u09ru49w*()9uE2R_)$I#Q)_ U383q04+RFJO{dgnkvlj b`kefl;nwdl qsa`WKFSA,.E
.onlyDigits:         2345425241309499238304
.onlyLetters:        fgdorivwerDWEJwiuruwuERIQUqRFJOdgnkvljbkeflnwdlqsaWKFSAE

4
投票

试试这个:

let string = "(555) 555-5555"
let digitString = string.filter { ("0"..."9").contains($0) }
print(digitString) // 5555555555

放入扩展:

extension String
{
    var digitString: String { filter { ("0"..."9").contains($0) } }
}

print("(555) 555-5555".digitString) // 5555555555

2
投票

您需要使用 NSCharacterSet:

查看此 NSHipster 链接以了解 Swift 和 Obj-C 实现: http://nshipster.com/nscharacterset/

类似例子:

var string = "  Lorem    ipsum dolar   sit  amet. "

let components = string.componentsSeparatedByCharactersInSet(NSCharacterSet.whitespaceCharacterSet()).filter({!isEmpty($0)})

string = join(" ", components)

参见:标点字符集

描述:

返回包含标点符号类别中的字符的字符集。 非正式地,该集合是用于分隔脚本中的语言单元的所有非空白字符的集合,例如句点、破折号、括号等。

@Tapani 提出了一个很好的建议:

NSCharacterSet.decimalDigitCharacterSet().invertedSet


1
投票

这是@Tapani Swift 3.2 解决方案

let phno = contact.phoneNumbers[0].phoneNumber
let strarr = phno.components(separatedBy: NSCharacterSet.decimalDigits.inverted)
let newString = NSArray(array: strarr).componentsJoined(by: "")
print(newString)

1
投票

我找到了带有过滤功能的最佳解决方案。请看一下。

let string = "(555) 555-5555"

let onlyDigits = string.filter({ (char) -> Bool in

    if Int("\(char)") != nil {

        return true
    }
    else {

        return false
    }

})

1
投票

没有准确回答,但看起来像一个数字。 我使用 URLComponents 来构建 url,因为它会自动去掉括号和破折号:

var telUrl: URL? {
    var component = URLComponents()
    component.scheme = "tel"
    component.path = "+49 (123) 1234 - 56789"
    return component.url
}

然后

UIApplication.shared.open(telUrl, options: [:], completionHandler: nil)

致电 +49 123 123456789


0
投票

字符集

.decimalDigits
不仅包含ASCII数字0-9,还包含例如以下字符:“𝟙१᠑⅚㊈𝟠๒”。

我发现使用以下代码更好:

extension String {
    var digits: String {
        filter { $0.isNumber && $0.isASCII }
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.