rubyguides

String#split

split(pattern = $;, limit = nil)

#split divides a string into an array of substrings based on a delimiter, returning the result. It is one of the most commonly used string methods in Ruby — essential for parsing CSV data, processing log lines, tokenising natural language, and transforming delimited text into structured data.

Basic Syntax

str.split(pattern = $;, limit = nil)
ArgumentDescription
patternDelimiter to split on — a string, regex, or nil (splits on whitespace)
limitMaximum number of splits (controls array length)

When pattern is nil, split treats consecutive whitespace as a single delimiter and removes leading and trailing whitespace from the result. When pattern is an empty string (""), the string is split into individual characters.

Splitting on a String Delimiter

"apple,banana,cherry".split(",")
# => ["apple", "banana", "cherry"]

"one::two::three".split("::")
# => ["one", "two", "three"]

"hello world".split(" ")
# => ["hello", "world"]

The delimiter can be any string — not just single characters.

Splitting on Whitespace (nil pattern)

"foo bar baz".split
# => ["foo", "bar", "baz"]

"  foo   bar\nbaz  ".split
# => ["foo", "bar", "baz"]

# Leading and trailing whitespace is trimmed
"   one   two   ".split
# => ["one", "two"]

Using nil as the pattern is the idiomatic way to split on any whitespace without having to call strip first.

Splitting into Individual Characters (empty string pattern)

"hello".split("")
# => ["h", "e", "l", "l", "o"]

"12345".split("")
# => ["1", "2", "3", "4", "5"]

An empty string as the delimiter splits between every character. The inverse operation is "hello".chars or "hello".chars.join.

Using a Regex Pattern

"foo bar baz".split(/\s+/)
# => ["foo", "bar", "baz"]

"apple1banana2cherry".split(/\d+/)
# => ["apple", "banana", "cherry"]

"one,two;three:four".split(/[,;:]/)
# => ["one", "two", "three", "four"]

Using a regex as the pattern gives you flexible delimiters — multiple characters, character classes, optional whitespace, and so on. Capturing groups in the regex are included in the result array:

"hello world".split(/(\s+)/)
# => ["hello", " ", "world"]

The Limit Parameter

The limit argument controls how many elements the returned array has:

"a:b:c:d".split(":", 2)
# => ["a", "b:c:d"]

"a:b:c:d".split(":", 3)
# => ["a", "b", "c:d"]

"a:b:c:d".split(":", 4)
# => ["a", "b", "c", "d"]

# limit = 0 means no limit (same as nil)
"a:b:c:d".split(":", 0)
# => ["a", "b", "c", "d"]

When limit is greater than 1, the array contains at most limit - 1 splits, and the last element contains the remainder of the string. When limit = 0, it behaves as if limit was nil (no limit), but trailing empty strings are removed.

Trailing Empty Strings

Without a limit, trailing empty strings are removed from the result:

"one::two::".split("::")
# => ["one", "two"]

# With limit = -1, trailing empties are preserved
"one::two::".split("::", -1)
# => ["one", "two", ""]

Passing -1 as the limit behaves like nil (no limit) but preserves trailing empty strings.

Preserving Empty Strings

To always include empty strings (for example, parsing fixed-width fields):

"a,,b,,c".split(",", -1)
# => ["a", "", "b", "", "c"]

# vs default behaviour
"a,,b,,c".split(",")
# => ["a", "", "b", "", "c"]  — trailing empty removed

Passing -1 as the limit preserves all empty strings.

Splitting Lines

For line-by-line splitting, use String#lines or String#split with "\n":

text = "line one\nline two\nline three"
text.split("\n")
# => ["line one", "line two", "line three"]

# With portable line endings (cross-platform)
text.split(/\r?\n/)
# => ["line one", "line two", "line three"]

split("\n") treats \n as a delimiter — note that trailing \n produces a trailing empty string. lines preserves the line endings as part of each element.

Inverse Operation

Use Array#join to recombine:

parts = "apple,banana,cherry".split(",")
parts.join(", ")
# => "apple, banana, cherry"

["one", "two", "three"].join(" -> ")
# => "one -> two -> three"

See Also