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
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 .
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.
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()
}
}
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
}
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
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) }
}
}
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)
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))
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"
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
Swift 3
extension String {
var keepNumericsOnly: String {
return self.components(separatedBy: CharacterSet(charactersIn: "0123456789").inverted).joined(separator: "")
}
}
Swift 4.0 Version
extension String {
var numbers: String {
return String(describing: filter { String($0).rangeOfCharacter(from: CharacterSet(charactersIn: "0123456789")) != nil })
}
}
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
Swift 4.2
let numericString = string.filter { (char) -> Bool in
return char.isNumber
}
Swift 4.2
let digitChars = yourString.components(separatedBy:
CharacterSet.decimalDigits.inverted).joined(separator: "")
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"
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
}
}