22

I am trying to trim a phone number and using the following code but it does not trim whitespace or the '-'. I need to erase all chars except those in the character set given

 func trimmedNumber(s : String)->String
 {
    let characterSet = NSCharacterSet(charactersInString: "+*#0123456789")
   let trimmedString =  s.stringByTrimmingCharactersInSet(characterSet.invertedSet)
    return trimmedString
}
tech74
  • 1,609
  • 1
  • 20
  • 39
  • Your code does exactly what you want. I tried in a Playground and it's removing whitespace and "-". ([screenshot](https://www.evernote.com/shard/s236/sh/298dec5a-a493-4501-8a09-1092a6490b88/9db22252948663c5/res/ce293b62-a398-4bbf-93e1-9a934a2a2733/skitch.png)) – Eric Aya Aug 28 '15 at 11:22
  • @EricD. try it on string "5467-rf34". This code doesn't work. – egor.zhdan Aug 28 '15 at 11:23
  • 3
    @egor.zhdan Actually this is expected: the [documentation](https://developer.apple.com/library/mac/documentation/Cocoa/Reference/Foundation/Classes/NSString_Class/#//apple_ref/occ/instm/NSString/stringByTrimmingCharactersInSet:) says stringByTrimmingCharactersInSet "Returns a new string made by removing from *both ends* of the receiver characters contained in a given character set." – Eric Aya Aug 28 '15 at 11:31
  • @EricD. yes, I understand, but don't know how to remove characters not only from ends of the string. – egor.zhdan Aug 28 '15 at 11:35

4 Answers4

36

Swift 3/4:

let set = CharacterSet(charactersIn: "+*#0123456789")
let stripped = s.components(separatedBy: set.inverted).joined()
dalton_c
  • 6,876
  • 1
  • 33
  • 42
9
func trimmedNumber(s : String) -> String {
  let characterSet = Set("+*#0123456789".characters)
  return String(s.characters.lazy.filter(characterSet.contains))
}

Or in Swift 1:

func trimmedNumber(s : String) -> String {
  let characterSet = Set("+*#0123456789")
  return String(lazy(s).filter { characterSet.contains($0) })
}
oisdk
  • 9,763
  • 4
  • 18
  • 36
5

Add the method removingCharacters(in:) to Swift's String type. It returns a new string made by removing the characters in a given character set from the String.

For example:

let string = "+1-202-555-0141"
let set = CharacterSet(charactersIn: "+*#0123456789")
let sanitized = string.removingCharacters(in: set.inverted)
// sanitized is equal to "+12025550141"

Helpers.swift

extension String {
  public func removingCharacters(in set: CharacterSet) -> String {
    let filtered = unicodeScalars.filter { !set.contains($0) }
    return String(String.UnicodeScalarView(filtered))
  }
}

HelpersTests.swift

import XCTest

class HelpersTests: XCTestCase {
  func testRemovingCharacters() {
    let inputText1 = ""
    let set1 = CharacterSet.decimalDigits.inverted
    let sanitized1 = inputText1.removingCharacters(in: set1)
    XCTAssertEqual("", sanitized1)

    let inputText2 = " tab:\tspace: no-break_space: "
    let set2 = CharacterSet.whitespaces
    let sanitized2 = inputText2.removingCharacters(in: set2)
    XCTAssertEqual("tab:space:no-break_space:", sanitized2)

    let inputText3 = " aBc!@#12 $%^&*()-_=+[{]}\\|;:'\"3,<.>/?`~ "
    let set3 = CharacterSet.alphanumerics.inverted
    let sanitized3 = inputText3.removingCharacters(in: set3)
    XCTAssertEqual("aBc123", sanitized3)
  }
}

See also: Convert Array of UnicodeScalar into String in Swift

ma11hew28
  • 121,420
  • 116
  • 450
  • 651
  • 1
    Why did you go for `lazy` in `unicodeScalars.lazy.filter`? Aren't we using it just below it? – Michal Šrůtek Apr 30 '20 at 06:33
  • @MichalŠrůtek, thanks for asking. Great question! I don't know. I had asked a similar question about [oisdk's answer](https://stackoverflow.com/a/32270113/242933). I think you're right though, so I removed the `.lazy` from `unicodeScalars.lazy`. Thanks! :-) – ma11hew28 Apr 30 '20 at 11:16
3

works in swift 1&2

let s = "adasdad+3124124+r323*4asdasdbk*($&#@"

let characterSet = NSCharacterSet(charactersInString: "+*#0123456789").invertedSet;
let elements = s.componentsSeparatedByCharactersInSet(characterSet)
let filtered = (elements as NSArray).componentsJoinedByString("")

print(filtered);
    
Olcay Ertaş
  • 5,987
  • 8
  • 76
  • 112
Daij-Djan
  • 49,552
  • 17
  • 113
  • 135