web-dev-qa-db-fra.com

Filtrer les non-chiffres de la chaîne

En utilisant uniquement le code Swift, je ne vois pas comment prendre "(555) 555-5555" et ne renvoyer que les valeurs numériques et obtenir "5555555555". Je dois supprimer toutes les parenthèses, les espaces et le tiret. Les seuls exemples que je puisse trouver sont ceux de l’objectif C et tous semblent utiliser la méthode .trim (). Il semble que Swift n’ait pas cette méthode, mais la méthode .stringByTrimmingCharacters, mais cela ne semble que rogner les espaces avant et après les données. 

34
Jeff Dicket

Swift 3 & 4:

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

Divisez la chaîne en caractères non numériques en un tableau de chiffres et reliez-les en une chaîne:

Swift 1:

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

Swift 2:

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

Swift 3 & 4:

let newString = origString
    .components(separatedBy:CharacterSet.decimalDigits.inverted)
    .joined(separator: "")
45
Tapani

J'aime les expressions régulières:

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

Voici la réponse Swift 2.0 de @ Tapani sous la forme d'une extension String pratique (la propriété length ne fait pas partie de la solution mais je l'ai laissée dans l'exemple car elle est également pratique):

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
    }

}

Usage:

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

Dans Swift 4, la solution est plus agréable:

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
3
werediver

Détails

xCode 8.2.1, Swift 3

Idée

Supprimer les jeux de caractères de la chaîne

Filtrer la chaîne dans Swift

import Foundation

extension String {

    private func removeCharacters(unicodeScalarsFilter: (UnicodeScalar) -> Bool) -> String {
        let filtredUnicodeScalars = unicodeScalars.filter{unicodeScalarsFilter($0)}
        return String(String.UnicodeScalarView(filtredUnicodeScalars))
    }

    private func removeCharacters(from charSets: [CharacterSet], unicodeScalarsFilter: (CharacterSet, UnicodeScalar) -> Bool) -> String {
        return removeCharacters{ unicodeScalar in
            for charSet in charSets {
                let result = unicodeScalarsFilter(charSet, unicodeScalar)
                if result {
                    return true
                }
            }
            return false
        }
    }

    func removeCharacters(charSets: [CharacterSet]) -> String {
        return removeCharacters(from: charSets) { charSet, unicodeScalar in
            !charSet.contains(unicodeScalar)
        }
    }

    func removeCharacters(charSet: CharacterSet) -> String {
        return removeCharacters(charSets: [charSet])
    }

    func onlyCharacters(charSets: [CharacterSet]) -> String {
        return removeCharacters(from: charSets) { charSet, unicodeScalar in
            charSet.contains(unicodeScalar)
        }
    }

    func onlyCharacters(charSet: CharacterSet) -> String {
        return onlyCharacters(charSets: [charSet])
    }
}

Usage

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 [.decimalDigits, .symbols]:     \(string.onlyCharacters(charSets: [.decimalDigits, .symbols]))")
print("remove .decimalDigits:               \(string.removeCharacters(charSet: .decimalDigits))")
print("remove [.decimalDigits, .symbols]:   \(string.removeCharacters(charSets: [.decimalDigits, .symbols]))")

Résultat

 enter image description here

Extension pour le code ci-dessus

Une petite idée pour le filtre rapide de création. Ceci est une extension du code écrit ci-dessus

Extension de code

extension String {

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

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

Utilisation de l'extension de code

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)")

Résultat de l'extension du code

 enter image description here

1
Vasily Bodnarchuk

Vous voudrez utiliser NSCharacterSet: 

Consultez ce lien NSHipster pour les implémentations de Swift et Obj-C: http://nshipster.com/nscharacterset/

Exemple similaire:

var string = "  Lorem    ipsum dolar   sit  amet. "

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

string = join(" ", components)

Voir: punctuationCharacterSet

La description:

Renvoie un jeu de caractères contenant les caractères de la catégorie Ponctuation . De manière informelle, il s'agit de l'ensemble des caractères autres que des espaces, utilisés pour séparer les unités linguistiques dans les scripts, tels que les points, les tirets, les parenthèses, etc.

@Tapani Fait une excellente suggestion: NSCharacterSet.decimalDigitCharacterSet().invertedSet

1
NSWill

J'avais un problème similaire mais je devais conserver les points décimaux. J'ai modifié la réponse à cette question:

extension String {

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

Voici la solution @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)
0
Sabrina Tuli

Pas exactement, mais cela ressemble à un nombre .J'ai utilisé URLComponents pour construire l'URL car elle supprime automatiquement les parenthèses et les tirets:

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

puis 

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

appels +49 123 123456789

0
mbnz

J'ai trouvé la meilleure solution avec la fonction de filtrage. S'il vous plaît jeter un oeil à ce sujet.

let string = "(555) 555-5555"

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

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

        return true
    }
    else {

        return false
    }

})
0
Naresh