Using only swift code I cant figure out how to take "(555) 555-5555" and return only the numeric values and get "5555555555". I need to remove all the parentheses, white spaces, and the dash. The only examples I can find are in objective-C and they seem to all use the .trim() method. It appears as though swift doesn't have this method but it does have the .stringByTrimmingCharacters method, but that only seems to trim the white spaces before and after the data.
-
4None of the "trim" methods will work since they only remove character from the ends of the string. – rmaddy Apr 30 '15 at 15:20
12 Answers
Swift 3 & 4
extension String {
var digits: String {
return components(separatedBy: CharacterSet.decimalDigits.inverted)
.joined()
}
}
Swift 5
You should be able to omit return
Also: Read the comment from @onmyway133 for a word of caution

- 1,309
- 2
- 12
- 18
-
16`return components(separatedBy: CharacterSet.decimalDigits.inverted).joined()` – Leo Dabus Dec 16 '16 at 20:08
-
2Note that `decimalDigits` may contain more than just numbers https://ravron.com/2019/07/how-many-decimal-digits-are-there-anyways/ – onmyway133 Feb 25 '21 at 08:25
Split the string by non-digit characters to an array of digits and the join them back to a string:
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()

- 11,454
- 9
- 54
- 64

- 3,191
- 1
- 25
- 41
-
-
1This saved me some time, as a suggestion, the second line can be replaced by simply stringArray.joinWithSeperator("") – Derek Hewitt Oct 14 '15 at 06:32
-
I like regular expressions:
var s = "(555) 555-5555"
s = s.stringByReplacingOccurrencesOfString(
"\\D", withString: "", options: .RegularExpressionSearch,
range: s.startIndex..<s.endIndex)

- 515,959
- 87
- 875
- 1,141
-
6Thanks for your answer! One small addition: I found that a better regex to use is `[^\\d+]`, leaving the valid + character intact. – jeppeb May 08 '16 at 08:55
In Swift 4 the solution is more nice:
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

- 4,667
- 1
- 29
- 49
Here is @Tapani's Swift 2.0 answer as a handy String extension, (length property is not part of solution but I left it in example because it is also handy):
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())

- 18,439
- 10
- 97
- 176
I had a similar issue but I needed to retain the decimal points. I tweaked the top answer to this:
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()
}
}

- 8,228
- 4
- 50
- 65
Details
- Xcode Version 10.2.1 (10E1001), Swift 5
Solution
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]) }
}
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 [.lowercaseLetters, .symbols]: \(string.onlyCharacters(charSets: [.lowercaseLetters, .symbols]))")
print("remove .letters: \(string.removeCharacters(charSet: .letters))")
print("remove [.decimalDigits, .lowercaseLetters]: \(string.removeCharacters(charSets: [.decimalDigits, .lowercaseLetters]))")
Result
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
(Optional) String extension
extension String {
var onlyDigits: String { return onlyCharacters(charSets: [.decimalDigits]) }
var onlyLetters: String { return onlyCharacters(charSets: [.letters]) }
}
(Optional) String extension 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(".onlyDigits: \(string.onlyDigits)")
print(".onlyLetters: \(string.onlyLetters)")
(Optional) String extension usage result
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

- 24,482
- 9
- 132
- 127
Try this:
let string = "(555) 555-5555"
let digitString = string.filter { ("0"..."9").contains($0) }
print(digitString) // 5555555555
Putting in extension:
extension String
{
var digitString: String { filter { ("0"..."9").contains($0) } }
}
print("(555) 555-5555".digitString) // 5555555555

- 1,583
- 3
- 23
- 34
-
how simple and elegant, best answer out here! even shorter would be `string.filter(("0"..."9").contains)` – ramzesenok Nov 28 '22 at 12:07
You'll want to use NSCharacterSet:
Check out this NSHipster link for Swift and Obj-C implementations: http://nshipster.com/nscharacterset/
Similar example:
var string = " Lorem ipsum dolar sit amet. "
let components = string.componentsSeparatedByCharactersInSet(NSCharacterSet.whitespaceCharacterSet()).filter({!isEmpty($0)})
string = join(" ", components)
See: punctuationCharacterSet
Description:
Returns a character set containing the characters in the category of Punctuation. Informally, this set is the set of all non-whitespace characters used to separate linguistic units in scripts, such as periods, dashes, parentheses, and so on.
@Tapani Makes a great suggestion:
NSCharacterSet.decimalDigitCharacterSet().invertedSet
Here is @Tapani Swift 3.2 solution
let phno = contact.phoneNumbers[0].phoneNumber
let strarr = phno.components(separatedBy: NSCharacterSet.decimalDigits.inverted)
let newString = NSArray(array: strarr).componentsJoined(by: "")
print(newString)

- 160
- 7
I found the best solution with filter function. Please have a look into it.
let string = "(555) 555-5555"
let onlyDigits = string.filter({ (char) -> Bool in
if Int("\(char)") != nil {
return true
}
else {
return false
}
})

- 869
- 8
- 17
-
-
-
-
Interesting thought. I was assuming that the parsing and constructing an Int would be more complex. But then, looking at it, it only has a single character to work on which probably has some simple manipulation of the of the ascii value under the covers. – altimes Aug 28 '21 at 04:42
Not exactly answered but it looks like a number. I used URLComponents to build the url because it strips out parenthesis and dashes automatically:
var telUrl: URL? {
var component = URLComponents()
component.scheme = "tel"
component.path = "+49 (123) 1234 - 56789"
return component.url
}
then
UIApplication.shared.open(telUrl, options: [:], completionHandler: nil)
calls +49 123 123456789

- 73
- 8