web-dev-qa-db-de.com

Entfernen Sie schnell alle nicht numerischen Zeichen aus einer Zeichenfolge

Ich muss einige unbekannte Daten analysieren, die nur einen numerischen Wert haben sollen, aber Leerzeichen oder andere nicht alphanumerische Zeichen enthalten können.

Gibt es in Swift einen neuen Weg, dies zu tun? Alles, was ich online finden kann, scheint der alte Weg des C zu sein. 

Ich betrachte stringByTrimmingCharactersInSet - da ich sicher bin, dass meine Eingaben am Anfang oder Ende der Zeichenfolge nur Leerzeichen/Sonderzeichen enthalten. Gibt es integrierte Zeichensätze, die ich dafür verwenden kann? Oder muss ich meine eigenen erstellen?

Ich hatte gehofft, dass es so etwas wie stringFromCharactersInSet() geben würde, das mir erlaubt, nur gültige Zeichen anzugeben, die beibehalten werden sollen

51
Dan

Ich hatte gehofft, es würde so etwas wie stringFromCharactersInSet () geben, das mir erlaubt, nur gültige Zeichen anzugeben, die beibehalten werden sollen.

Sie können entweder trimmingCharacters mit dem Zeichensatz inverted verwenden, um Zeichen vom Anfang oder vom Ende der Zeichenfolge zu entfernen. In Swift 3 und später:

let result = string.trimmingCharacters(in: CharacterSet(charactersIn: "01234567890.").inverted)

Wenn Sie nichtnumerische Zeichen an einer beliebigen Stelle in der Zeichenfolge entfernen möchten (nicht nur am Anfang oder am Ende), können Sie filter die characters, z. in Swift 4.2.1:

let result = string.filter("01234567890.".contains)

Wenn Sie nur gültige Zeichenfolgen eines bestimmten Formats (z. B. ####.##) abgleichen möchten, können Sie reguläre Ausdrücke verwenden. Zum Beispiel:

if let range = string.range(of: "\\d+(\\.\\d*)?", options: .regularExpression) {
    let result = string[range] // or `String(string[range])` if you need `String`
}

Das Verhalten dieser verschiedenen Ansätze unterscheidet sich geringfügig. Es hängt also davon ab, was Sie genau tun. Schließen Sie das Dezimalzeichen ein oder aus, wenn Sie Dezimalzahlen oder nur ganze Zahlen wünschen. Es gibt viele Möglichkeiten, dies zu erreichen.


Für ältere Swift-2-Syntax siehe vorherige Überarbeitung dieser Antwort .

96
Rob
let result = string.stringByReplacingOccurrencesOfString("[^0-9]", withString: "", options: NSStringCompareOptions.RegularExpressionSearch, range:nil).stringByTrimmingCharactersInSet(NSCharacterSet.whitespaceCharacterSet())

Swift 3

let result = string.replacingOccurrences( of:"[^0-9]", with: "", options: .regularExpression)

Sie können diese Antwort bestätigen. 

29
Tom Howard

Ich bevorzuge diese Lösung , weil ich Erweiterungen mag und mir ein bisschen sauberer vorkommt. Lösung hier reproduziert:

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

Swift 4

Ich habe einen guten Weg gefunden, um nur alphanumerisch Zeichensatz aus einem String zu erhalten. Zum Beispiel:-

func getAlphaNumericValue() {

    var yourString  = "[email protected]#$%^&*()AnyThingYouWant"

    let unsafeChars = CharacterSet.alphanumerics.inverted  // Remove the .inverted to get the opposite result.  

    let cleanChars  = yourString.components(separatedBy: unsafeChars).joined(separator: "")


    print(cleanChars)  // 123456789AnyThingYouWant

}
11
Aashish

Eine Lösung mit der filter-Funktion und rangeOfCharacterFromSet

let string = "sld [f]34é7*˜µ"

let alphaNumericCharacterSet = NSCharacterSet.alphanumericCharacterSet()
let filteredCharacters = string.characters.filter {
  return  String($0).rangeOfCharacterFromSet(alphaNumericCharacterSet) != nil
}
let filteredString = String(filteredCharacters) // -> sldf34é7µ

Um nur nach numerischen Zeichen zu filtern, verwenden Sie

let string = "sld [f]34é7*˜µ"

let numericSet = "0123456789"
let filteredCharacters = string.characters.filter {
  return numericSet.containsString(String($0))
}
let filteredString = String(filteredCharacters) // -> 347

oder

let numericSet : [Character] = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9"]
let filteredCharacters = string.characters.filter {
  return numericSet.contains($0)
}
let filteredString = String(filteredCharacters) // -> 347
10
vadian

Sie können die UnicodeScalarView der Zeichenfolge mit dem Musterabgleichoperator nach Bereichen filtern, einen UnicodeScalar ClosedRange von 0 bis 9 übergeben und eine neue Zeichenfolge mit der resultierenden UnicodeScalarView initialisieren:

extension String {
    private static var digits = UnicodeScalar("0")..."9"
    var digits: String {
        return String(unicodeScalars.filter(String.digits.contains))
    }
}

"abc12345".digits   // "12345"

bearbeiten/Aktualisieren:

Swift 4.2

extension RangeReplaceableCollection where Self: StringProtocol {
    var digits: Self {
        return filter(("0"..."9").contains)
    }
}

oder als Mutationsmethode

extension RangeReplaceableCollection where Self: StringProtocol {
    mutating func removeAllNonNumeric() {
        removeAll { !("0"..."9" ~= $0) }
    }
}
5
Leo Dabus

Swift 3, filtert alle außer Zahlen

let myString = "dasdf3453453fsdf23455sf.2234"
let result = String(myString.characters.filter { String($0).rangeOfCharacter(from: CharacterSet(charactersIn: "0123456789")) != nil })
print(result)
4
CodeOverRide

Swift 4

Aber ohne Erweiterungen oder KomponentenSeparatedByCharactersInSet, die nicht gut lesen.

let allowedCharSet = NSCharacterSet.letters.union(.whitespaces)
let filteredText = String(sourceText.unicodeScalars.filter(allowedCharSet.contains))
3
Steve Moser

Sie können so etwas tun ...

let string = "[,myString1. \"" // string : [,myString1. " 
let characterSet = NSCharacterSet(charactersInString: "[,. \"")
let finalString = (string.componentsSeparatedByCharactersInSet(characterSet) as NSArray).componentsJoinedByString("") 
print(finalString)   
//finalString will be "myString1"
2
vivek takrani

Das Problem bei Robs erster Lösung ist, dass stringByTrimmingCharactersInSet nur die Enden der Zeichenfolge filtert und nicht durchgängig, wie in der Apple-Dokumentation angegeben:

Gibt eine neue Zeichenfolge zurück, die durch Entfernen der in einem bestimmten Zeichensatz enthaltenen Empfängerzeichen an beiden Enden erstellt wurde.

Verwenden Sie stattdessen componentsSeparatedByCharactersInSet , um zunächst alle Nicht-Vorkommen des Zeichensatzes in Arrays zu isolieren und diese anschließend mit einem leeren Trennzeichen zu verbinden:

"$$1234%^56()78*9££".componentsSeparatedByCharactersInSet(NSCharacterSet(charactersInString: "0123456789").invertedSet)).joinWithSeparator("")

Welche gibt 123456789 zurück

2
Ryan Brodie

Swift 3

extension String {
    var keepNumericsOnly: String {
        return self.components(separatedBy: CharacterSet(charactersIn: "0123456789").inverted).joined(separator: "")
    }
}
2
Ehab Saifan

Swift 4.0 Version

extension String {
    var numbers: String {
        return String(describing: filter { String($0).rangeOfCharacter(from: CharacterSet(charactersIn: "0123456789")) != nil })
    }
}
1
rockdaswift

Schnell 4

String.Swift

import Foundation

extension String {

    func removeCharacters(from forbiddenChars: CharacterSet) -> String {
        let passed = self.unicodeScalars.filter { !forbiddenChars.contains($0) }
        return String(String.UnicodeScalarView(passed))
    }

    func removeCharacters(from: String) -> String {
        return removeCharacters(from: CharacterSet(charactersIn: from))
    }
}

ViewController.Swift

let character = "1Vi234s56a78l9"
        let alphaNumericSet = character.removeCharacters(from: CharacterSet.decimalDigits.inverted)
        print(alphaNumericSet) // will print: 123456789

        let alphaNumericCharacterSet = character.removeCharacters(from: "0123456789")
        print("no digits",alphaNumericCharacterSet) // will print: Vishal
1

Swift 4.2

let numericString = string.filter { (char) -> Bool in
    return char.isNumber
}
0
mef27

Swift 4.2

let digitChars  = yourString.components(separatedBy:
        CharacterSet.decimalDigits.inverted).joined(separator: "")
0
Debaprio B
let string = "+1*(234) [email protected]/90-"
let onlyNumbers = string.components(separatedBy: CharacterSet.decimalDigits.inverted).joined()

print(onlyNumbers) // "1234567890"

oder

extension String {

  func removeNonNumeric() -> String {
    return self.components(separatedBy: CharacterSet.decimalDigits.inverted).joined()
  }
}

let onlyNumbers = "+1*(234) [email protected]/90-".removeNonNumeric() 
print(onlyNumbers)// "1234567890"
0

Swift 3 Version

extension String
{
    func trimmingCharactersNot(in charSet: CharacterSet) -> String
    {
        var s:String = ""
        for unicodeScalar in self.unicodeScalars
        {
            if charSet.contains(unicodeScalar)
            {
                s.append(String(unicodeScalar))
            }
        }
        return s
    }
}
0
hhamm