Start learning free

LESSON 65 OF 415 · STRINGS I

Trimming Whitespace in Swift: trimmingCharacters(in:)

Lesson Read the full explanation

In Swift, you can remove leading and trailing whitespace from a string using trimmingCharacters(in:), which comes from Foundation, so a standalone file needs import Foundation at the top:

s.trimmingCharacters(in: .whitespaces)              // removes leading and trailing whitespace
s.trimmingCharacters(in: .whitespacesAndNewlines)   // removes whitespace and newlines from both ends

Here are some examples:

import Foundation

let s = "  hello  "
print(s.trimmingCharacters(in: .whitespaces))              // "hello"
print(s.trimmingCharacters(in: .whitespacesAndNewlines))   // "hello"

These methods return a new String — the original is not modified.


Assignment
Follow the Coding Tutorial and strip whitespace from text!


Hint
Use text.trimmingCharacters(in: .whitespaces) and assign the result to result.

STEP 1 OF 1
    Ctrl + Enter to check

    SWIFT · STRINGS I

    String Strip in Swift, explained

    Removing whitespace from the ends

    Text from users and files often has extra spaces at the start or end. Swift's way to remove them is trimmingCharacters(in:). It comes from Foundation, so a standalone file needs import Foundation at the top. You tell it which characters to strip by passing a character set, and it removes those characters from both ends of the string until it meets one that isn't in the set.

    import Foundation
    
    let text = "  hello  "
    let result = text.trimmingCharacters(in: .whitespaces)
    print("[" + result + "]")
    print("[" + text + "]")
    print(result.count, text.count)
    
    [hello]
    [  hello  ]
    5 9
    

    The last line shows the lengths, 5 for the trimmed string and 9 for the original. The method returns a new string and leaves the original alone, so the result has to be stored or used.

    Which characters count

    Two common sets are:

    • .whitespaces covers spaces and tabs, but not line breaks.
    • .whitespacesAndNewlines also covers line breaks.

    The difference shows on a string with a tab at the front and a newline at the back:

    import Foundation
    
    let line = "\t hi there \n"
    print(line.trimmingCharacters(in: .whitespaces).debugDescription)
    print(line.trimmingCharacters(in: .whitespacesAndNewlines).debugDescription)
    
    "hi there \n"
    "hi there"
    

    With .whitespaces the tab and leading space are removed, but the trailing space and newline stay, because the newline isn't in the set and stops the trimming at that end. Text read from a file usually ends with a newline, so .whitespacesAndNewlines is the one you often want.

    Only the ends

    Whitespace in the middle is never touched:

    import Foundation
    
    print("  a   b  ".trimmingCharacters(in: .whitespaces).debugDescription)
    print("   ".trimmingCharacters(in: .whitespaces).isEmpty)
    
    "a   b"
    true
    

    A string made only of whitespace is trimmed down to the empty string, which makes the trimmed isEmpty a handy check for "blank input".

    Trimming other characters

    The set doesn't have to be whitespace. CharacterSet(charactersIn:) builds a set from the characters of a string, and .punctuationCharacters is a ready-made set:

    import Foundation
    
    print("xxhixx".trimmingCharacters(in: CharacterSet(charactersIn: "x")))
    print("!!hi?!".trimmingCharacters(in: .punctuationCharacters))
    
    hi
    hi
    

    Cleaning input before comparing

    Stray spaces make equal-looking strings compare as different. Trim first, then compare:

    import Foundation
    
    let typed = "  yes "
    print(typed == "yes")
    print(typed.trimmingCharacters(in: .whitespaces) == "yes")
    
    false
    true
    

    The same habit applies before converting text to a number or looking a word up in a collection: clean the value first, so the extra characters don't cause a failed match.

    Without Foundation

    The standard library has no trimming method, so without Foundation you build one from drop(while:). Dropping from the front, reversing, dropping again and reversing back removes the spaces at both ends:

    let text = "  hello  "
    let front = text.drop(while: { $0 == " " })
    let trimmed = String(String(front.reversed()).drop(while: { $0 == " " }).reversed())
    print("[" + trimmed + "]")
    
    [hello]
    

    That is a lot of code for a small job, which is why the Foundation method is the usual choice.

    The exercise

    The constant text holds " hello ". Declare result with let as text.trimmingCharacters(in: .whitespaces). The print(result) that follows then shows hello without the surrounding spaces.

            let text = "  hello  "
    
            let result = text.trimmingCharacters(in: .whitespaces)
            print(result)
    
    hello
    

    Common mistakes

    • Expecting the original to change. The method returns a new string.
    • Using .whitespaces on text with a trailing newline. The newline stays. Use .whitespacesAndNewlines.
    • Expecting inner spaces to go. Only the two ends are trimmed. To remove spaces everywhere, replace them with an empty string.
    • Dropping the leading dot. The sets are written .whitespaces in this position, and the compiler works out the type from the parameter.

    Key takeaways

    • trimmingCharacters(in:) removes characters of the given set from both ends and returns a new string.
    • .whitespaces means spaces and tabs. .whitespacesAndNewlines adds line breaks.
    • It needs Foundation.
    Keep going with SwiftAbout 340 step-by-step lessons, from your first line of code to coding interviews. Free to start.
    Start learning free