How to trim whitespace from string

Use the built-in `trim()`, `trim_start()`, and `trim_end()` methods on string slices (`&str`) to remove leading, trailing, or both types of whitespace.

Use the built-in trim(), trim_start(), and trim_end() methods on string slices (&str) to remove leading, trailing, or both types of whitespace. These methods return a new string slice pointing to the trimmed portion of the original data without allocating new memory, making them efficient for read-only operations.

For mutable String types, use trim_start_mut() and trim_end_mut() to modify the string in place, which avoids allocation entirely by shrinking the string's length.

fn main() {
    let s = "   hello world   \n";

    // Returns a &str slice (no allocation)
    let trimmed = s.trim(); 
    println!("Trimmed: '{}'", trimmed); // Output: "hello world"

    let start_trimmed = s.trim_start();
    let end_trimmed = s.trim_end();

    // In-place modification for String
    let mut mutable_s = String::from("   rust   ");
    mutable_s.trim_start_mut();
    mutable_s.trim_end_mut();
    println!("Mutable: '{}'", mutable_s); // Output: "rust"
}

If you need to remove specific characters other than standard Unicode whitespace, use the trim_matches() method with a character or a closure. This is useful when dealing with custom delimiters or non-standard whitespace characters.

fn main() {
    let s = "###hello###";
    
    // Trim specific characters
    let trimmed = s.trim_matches('#');
    println!("Trimmed chars: '{}'", trimmed); // Output: "hello"

    // Trim using a closure for complex logic
    let s2 = "   hello   ";
    let trimmed_custom = s2.trim_matches(|c: char| c.is_whitespace() || c == ' ');
    println!("Custom trim: '{}'", trimmed_custom); // Output: "hello"
}

Remember that trim() and its variants do not modify the original string; they return a slice. If you need to store the result in a String, you must explicitly convert the slice using .to_string() or .to_owned(). This distinction is crucial for managing memory ownership correctly in Rust.

fn main() {
    let original = "   data   ";
    
    // Convert slice to owned String
    let owned: String = original.trim().to_string();
    
    println!("Owned: '{}'", owned);
    println!("Original unchanged: '{}'", original);
}