rubyguides

String#strip for Leading and Trailing Whitespace

strip removes whitespace from both ends of a string. Whitespace includes spaces, tabs, newlines, carriage returns, form feeds, and null bytes.

Use strip when the content is correct but the edges are messy. It is especially common after reading form fields, command output, CSV values, or lines from files. The method leaves whitespace inside the text alone, so it cleans the boundary without changing words in the middle.

Signature

str.strip → new_string

Returns: A new string with leading and trailing whitespace removed.

Because strip returns a new string rather than modifying the original, it is safe to call on string literals and frozen strings without worrying about side effects. The original stays unchanged, which fits well in functional-style pipelines where each transformation produces a fresh value. If you need in-place mutation, use the bang variant strip! instead.

Basic Usage

"  hello  ".strip
# => "hello"

"\tgoodbye\r\n".strip
# => "goodbye"

"  multiple   spaces   ".strip
# => "multiple   spaces"

The third example above is worth noting: spaces between words stay exactly where they are. The method only removes whitespace from the very beginning and the very end of the string, leaving the interior untouched. That property makes strip well-suited for cleaning up form inputs, CSV values, and lines read from files — cases where you want to remove accidental boundary padding without disturbing the meaningful content inside the text.

what counts as whitespace

Ruby defines whitespace as the characters matching /\s/, which includes:

  • " " (space)
  • "\t" (tab)
  • "\n" (newline)
  • "\r" (carriage return)
  • "\f" (form feed)
  • "\v" (vertical tab)
  • "\0" (null byte)
" \t\n\r\0\f\v hello \t\n\r\0\f\v ".strip
# => "hello"

Ruby keeps internal spacing intact. That makes strip safe for names, labels, and free-form text where spaces inside the value may be intentional. The method treats the string as having a leading edge and a trailing edge and only removes characters that sit outside the first and last non-whitespace characters. Everything between those two anchor points is left exactly as it was, whether that is a single space or a long run of tabs and spaces.

lstrip and rstrip

Remove from one end only:

# left side only
"  hello  ".lstrip
# => "hello  "

# right side only
"  hello  ".rstrip
# => "  hello"

Each of the three variants has a bang counterpart — strip!, lstrip!, and rstrip! — that modifies the receiver in place rather than allocating a new string. The bang form returns the modified string when whitespace was actually removed, but returns nil when the string was already clean and no changes were made. This nil-on-no-op convention is consistent across Ruby’s String methods and lets you detect whether any stripping happened by checking the return value:

original = "  hello  "
original.strip!
# => "hello"
original
# => "hello"

The distinction between lstrip, rstrip, and strip gives you fine-grained control over which side of the string gets cleaned. When parsing indented configuration files, you might want to strip only the leading indentation while keeping trailing spaces that are part of the value. When normalizing log output, you might only care about trailing newlines. Using the right variant makes the intent explicit and avoids accidentally removing whitespace that matters.

Practical Examples

cleaning user input

Form input often arrives with accidental whitespace:

def normalize(input)
  input.to_s.strip
end

normalize("  john.doe@example.com ")
# => "john.doe@example.com"

Normalizing user input with strip is a defensive habit that costs almost nothing and prevents a common class of bugs. When a user copies an email address or a name with surrounding spaces, the extra whitespace is invisible to them but can break string comparisons or database lookups. Calling to_s first handles nil inputs gracefully, making the helper safe to use on optional form fields without a separate nil check.

parsing line-oriented data

When reading lines from a file, strip removes the trailing newline and any extra padding:

File.readlines("data.csv").each do |line|
  name, value = line.strip.split(",")
  puts "#{name}: #{value}"
end

When reading lines from a file, each line typically ends with a newline character. Calling strip removes that newline along with any leading or trailing spaces, giving you clean values to work with. The pattern above combines strip with split to parse CSV-like data in one pass, which is practical for quick scripts and ad-hoc data processing where a full CSV parser would be overkill.

comparing strings gracefully

query = "  ruby  ".strip.downcase

if query == "ruby"
  puts "Exact match"
end

This comparison example normalizes both strings before checking equality, which is a simple but effective pattern for user-facing text. By calling strip and downcase on the input, the comparison becomes tolerant of accidental spaces and case differences without needing a complex matching algorithm. The approach works well for search queries, configuration keys, and any situation where minor formatting variations should not prevent a match.

in-place modification with strip!

The bang variant modifies the receiver:

s = "  text  "
result = s.strip!
# s is now "text"
# result is "text" (also returns the new string)

# If no whitespace, returns nil:
s2 = "text"
result2 = s2.strip!
# s2 is still "text"
# result2 is nil

The bang variant is convenient when you want to mutate a string in place, but the nil return on no-op adds a subtle edge case that trips up code that chains the return value without checking for nil first. When the string might already be clean, the non-bang strip is usually safer because it always returns a string, never nil. The pitfalls below cover additional edge cases where strip alone is not enough.

Common Pitfalls

non-breaking spaces

Unicode category U+00A0 (non-breaking space) is not removed by strip because it does not match /\s/:

"\u00A0hello\u00A0".strip
# => "\u00A0hello\u00A0" (unchanged)

# To remove non-breaking spaces too:
"\u00A0hello\u00A0".strip.gsub("\u00A0", "")
# => "hello"

Non-breaking spaces often appear after copying text from a browser or document editor. Handle them explicitly when your input source is likely to contain formatted text. Because strip only removes characters matching /\s/ in Ruby’s regular expression engine, Unicode whitespace characters outside that character class pass through unchanged, which can lead to subtle comparison failures if you do not account for them.

mixed whitespace in the middle

strip only removes from the ends, not the middle of the string:

"hello    world".strip
# => "hello    world" (middle spaces unchanged)

# For collapsing all whitespace:
"hello    world".split.join(" ")
# => "hello world"

That final pattern changes internal whitespace, so use it only when collapsed spacing is actually desired. For ordinary boundary cleanup, strip alone is the more conservative choice.

See Also