0

I want to remove every char that is not in this list: "0123456790." from a string

I tried:

let characters = NSCharacterSet(charactersIn: "0123456789.").inverted
string = string.replacingOccurrences(of: characters.allCharacters().description, with: "", options: .regularExpression)

extension CharacterSet {
    func allCharacters() -> [Character] {
        var result: [Character] = []
        for plane: UInt8 in 0...16 where self.hasMember(inPlane: plane) {
            for unicode in UInt32(plane) << 16 ..< UInt32(plane + 1) << 16 {
                if let uniChar = UnicodeScalar(unicode), self.contains(uniChar) {
                    result.append(Character(uniChar))
                }
            }
        }
        return result
    }
}
Marckaraujo
  • 7,422
  • 11
  • 59
  • 97
  • Possible duplicate of [How to remove special characters from string in Swift 2?](http://stackoverflow.com/questions/32851720/how-to-remove-special-characters-from-string-in-swift-2). – Martin R Nov 22 '16 at 14:06

5 Answers5

2

Using part of your code:

let charactersSet = NSCharacterSet(charactersIn: "0123456789.").inverted

extension String {
    func allCharacters() -> String {
        return self.components(separatedBy: charactersSet).joined()
    }
}
Sealos
  • 562
  • 3
  • 15
  • This code is slick, but I wonder how well it performs? Unless the compiler optimizes it, it will create a separate String object for every run of digits, requiring multiple memory allocations. Wouldn't it be faster to iterate through the source string, picking out the digits and appending them to an output string? (Since memory allocations are quite expensive) – Duncan C Nov 22 '16 at 14:03
  • You are correct, in a way, the way that you're proposing is almost as bad as this since swift creates a new string every time that you append. Anyways, I wouldn't take the time to optimize this unless it's necessary. – Sealos Nov 22 '16 at 14:13
  • It doesnt work for swift3, so I cant test if it is right. – Marckaraujo Nov 30 '16 at 17:26
  • It works with swift 3, however, strings have a property called characters, so it wasn't working. Try now. @Marckaraujo – Sealos Dec 01 '16 at 12:17
2

Swift 3

string = (string.components(separatedBy: NSCharacterSet(charactersIn: "0123456789.").inverted) as NSArray).componentsJoined(by: "")
Marckaraujo
  • 7,422
  • 11
  • 59
  • 97
1

Use this extension.

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

let test = "Hello 54-Today is 112216"
let fixed = test.digits
print(fixed) //54112216
TheValyreanGroup
  • 3,554
  • 2
  • 12
  • 30
0

This should do it

var newString = (origString.components(separatedBy: CharacterSet.decimalDigits.inverted) as NSArray).componentsJoined(byString: "").replacingOccurrences(of: ".", with: "", options: .literal, range: nil)
Alec.
  • 5,371
  • 5
  • 34
  • 69
0

In you could alter your first regex to include a space after the 9:

In swift:

var str = "test Test 333 9599 999";
val strippedStr = str.stringByReplacingOccurrencesOfString("[^0-9 ]",   withString: "", options: NSStringCompareOptions.RegularExpressionSearch, range:nil);
// strippedStr = " 33 9599 999"

While this leaves the leading space, you could apply a whitespace trimming to deal with that:

strippedStr.stringByTrimmingCharactersInSet(NSCharacterSet.whitespaceCharacterSet())
// strippedStr = "33 9599 999"