56

What is the most efficient way to remove all the spaces, \n and \r in a String in Swift?

I have tried:

for character in string.characters {

}

But it's a little inconvenient.

iGatiTech
  • 2,306
  • 1
  • 21
  • 45
Tauta
  • 907
  • 1
  • 8
  • 12

11 Answers11

99

Swift 4:

let text = "This \n is a st\tri\rng"
let test = String(text.filter { !" \n\t\r".contains($0) })

Output:

print(test) // Thisisastring

While Fahri's answer is nice, I prefer it to be pure Swift ;)

Eendje
  • 8,815
  • 1
  • 29
  • 31
  • I think `filter` is too expensive for this, what's wrong with `removeSubrange` or `stringByTrimmingCharacters`, etc? – kakubei Jul 07 '17 at 09:57
  • 5
    @kakubei : removeSubrange would mean you'd have to search the whole string for subranges, already as expensive as filtering before you even do any removing. stringByTrimmingCharacters only trims at the start and end of a string, not in the middle between words. – Kendall Helmstetter Gelner Aug 07 '17 at 18:34
  • 1
    Note that there is no need to initialize a new String. filter returns a String since Swift 4.x https://github.com/apple/swift-evolution/blob/master/proposals/0174-filter-range-replaceable.md – Leo Dabus May 08 '19 at 13:53
67

edit/update:

Swift 5.2 or later

We can use the new Character property isWhitespace


let textInput = "Line 1 \n Line 2 \n\r"
let result = textInput.filter { !$0.isWhitespace }

result  //  "Line1Line2"

extension StringProtocol where Self: RangeReplaceableCollection {
    var removingAllWhitespaces: Self {
        filter(\.isWhitespace.negated)
    }
    mutating func removeAllWhitespaces() {
        removeAll(where: \.isWhitespace)
    }
}

extension Bool {
    var negated: Bool { !self }
}

let textInput = "Line 1 \n Line 2 \n\r"
let result = textInput.removingAllWhitespaces   //"Line1Line2"

var test = "Line 1 \n Line 2 \n\r"
test.removeAllWhitespaces()
print(test)  // "Line1Line2"

Note: For older Swift versions syntax check edit history

Leo Dabus
  • 229,809
  • 59
  • 489
  • 571
26

For the sake of completeness this is the Regular Expression version

let string = "What is the most efficient way to remove all the spaces and \n \r \tin a String in Swift"
let stringWithoutWhitespace = string.replacingOccurrences(of: "\\s", with: "", options: .regularExpression)
// -> "WhatisthemostefficientwaytoremoveallthespacesandinaStringinSwift"
vadian
  • 274,689
  • 30
  • 353
  • 361
  • 1
    Thanks, this worked for me. Also I wanted to replace all the consecutive occurrences of \n, \r, \t or spaces with a single space, so I used "\\s+" and replaced with " ". let string = "this is an \n \t example" let newString = string.replacingOccurrences(of: "\\s+", with: " ", options: .regularExpression) //Result -> " this is an example" – Chuy47 Feb 07 '18 at 02:47
  • Do the swift regex `\s` include all from isNewline and isWhitespace ? – Mike Casan Ballester Jul 28 '19 at 15:27
  • 1
    @micaball In most regex flavors `\s` represents space, tab, linefeed, carriage return and formfeed (`[ \t\r\n\f]`) but not the special whitespace characters in the `0x2000` range. – vadian Jul 28 '19 at 15:33
7

For Swift 4:

let myString = "This \n is a st\tri\rng"
let trimmedString = myString.components(separatedBy: .whitespacesAndNewlines).joined()
L. Guthardt
  • 1,990
  • 6
  • 22
  • 44
  • filter is too expensive and i think for starter ones this will more useful..thats why i added –  Feb 27 '18 at 11:19
  • Ok, if you think so then it's fine. But then go ahead and explain your solution please. – L. Guthardt Feb 27 '18 at 11:20
4

If by spaces you mean whitespaces, be aware that more than one whitespace character exists, although they all look the same.

The following solution takes that into account:

Swift 5:

 extension String {

    func removingAllWhitespaces() -> String {
        return removingCharacters(from: .whitespaces)
    }

    func removingCharacters(from set: CharacterSet) -> String {
        var newString = self
        newString.removeAll { char -> Bool in
            guard let scalar = char.unicodeScalars.first else { return false }
            return set.contains(scalar)
        }
        return newString
    }
}


let noNewlines = "Hello\nWorld".removingCharacters(from: .newlines)
print(noNewlines)

let noWhitespaces = "Hello World".removingCharacters(from: .whitespaces)
print(noWhitespaces)
Pomeroy
  • 49
  • 1
  • 3
3

Use this:

let aString: String = "This is my string"
let newString = aString.stringByReplacingOccurrencesOfString(" ", withString: "", options:[], range: nil)
print(newString)

Output : Thisismystring

iAnurag
  • 9,286
  • 3
  • 31
  • 48
3

If anyone is wondering why, despite of putting "\n" and "\r" into the set, "\r\n" is not removed from the string, it's because "\r\n" is treated by swift as one character.

Swift 4:

let text = "\r\n This \n is a st\tri\rng"
let test = String(text.filter { !"\r\n\n\t\r".contains($0) })

"\n" is not duplicated by accident

Kamil
  • 31
  • 1
2

Suppose that you have this string : "some words \nanother word\n\r here something \tand something like \rmdjsbclsdcbsdilvb \n\rand finally this :)"

here the how to remove all possible space :

let possibleWhiteSpace:NSArray = [" ","\t", "\n\r", "\n","\r"] //here you add other types of white space
    var string:NSString = "some words \nanother word\n\r here something \tand something like \rmdjsbclsdcbsdilvb \n\rand finally this :)"
    print(string)// initial string with white space
    possibleWhiteSpace.enumerateObjectsUsingBlock { (whiteSpace, idx, stop) -> Void in
        string = string.stringByReplacingOccurrencesOfString(whiteSpace as! String, withString: "")
    }
    print(string)//resulting string

Let me know if this respond to your question :)

2

Swift 4:

let string = "Test\n with an st\tri\rng"
print(string.components(separatedBy: .whitespacesAndNewlines))
// Result: "Test with an string"
Haroldo Gondim
  • 7,725
  • 9
  • 43
  • 62
1

I just use this:

stringValue.replacingOccurrences(of: " ", with: "").replacingOccurrences(of: "\n", with: "")
-2

Swift 4:

let text = "This \n is a st\tri\rng"
let cleanedText = text.filter { !" \n\t\r".characters.contains($0) }
mag_zbc
  • 6,801
  • 14
  • 40
  • 62
tzuer
  • 321
  • 4
  • 12