Ruby Examples > Strings

#---Strings---

Any developer worth his salt should be able to wrangle strings to his needs.

Ruby provides so much string methods that you can walk around with a smirk like an old-western gunslinger who just put on his fully-loaded gun belt.

Creating Strings

There are many ways to create strings.

You can use either single or double quotes to create strings. But use double quotes if you need to interpolate any ruby code:

x = 42
puts 'answer is #{x}' # => answer is #{x}
puts "answer is #{x}" # => answer is 42

If you hate escaping special characters, use %Q{} or %q{}:

x = "Joe"
puts "Hi \"#{x}\"" # => Hi "Joe"
puts %q{Hi "#{x}"} # => Hi "#{x}"
puts %Q{Hi "#{x}"} # => Hi "Joe"

You can also use something else with %Q instead of {}:

puts %Q[Hi "#{x}"] # => Hi "Joe"

But please, stick to one as much as you can.

Use the weirdo ‘HEREDOCS’ if you want big, multi-line strings:

str = <<~BIGHAIRYSTRING
Meh.
  This squiggly heredoc respects
    the margin spaces and newlines.
BIGHAIRYSTRING
puts str
## => Meh.
## =>   This squiggly heredoc respects
## =>     the margin spaces and newlines.

Common String Methods

Find length of string using size or length. Both are same:

p "Boom 💥".size # => 6
p "Boom 💥".length # => 6

You can change a string’s case using upcase, downcase, capitalize.

p 'hi ruby'.upcase # => "HI RUBY"
p 'HI ruby'.downcase # => "hi ruby"
p 'HI ruby'.swapcase # => "hi RUBY"
p 'hi ruby'.capitalize # => "Hi ruby"

Reverse a string with reverse:

p 'esac'.reverse # => "case

The above methods don’t change the original string. They just return a new, modified string. But you can use the bang counterpart methods to change the original string itself.

x = 'hi ruby'
x.upcase!
p x # => "HI RUBY"

You can repeat a string ‘n’ times with the * method which looks cool:

p 'awesome possum ' * 2
## => "awesome possum awesome possum "

Checking the String for Something

Is the string empty?

p ''.empty? # => true
x = 'encyclopedia'
p x.empty? # => false

Does it include this substring?

p x.include?('cyclop') # => true

Does it start with or end with this substring?

p x.start_with?('en') # => true
p x.end_with?('meh') # => false

Find the index of the substring:

p x.index('cyclop') # => 2

Find the index of the substring from the right-side:

p 'slop slop'.index('slop') # => 0
p 'slop slop'.rindex('slop') # => 5

Now the opposite. Given an index or a range of indices, return the matching substring, aka ‘slicing’:

x = 'kaboom!'
p x[2] # => "b"
p x[2..4] # => "boo" (includes item at the ending index)
p x[2...4] # => "bo" (excludes it)
p x[2..-1] # => "boom!" (-1 means last item's index)

Modifying the String

Add 2 or more strings and return a new one:

a, b, c = 'Hello ', 'World', '!'
d = a + b + c
p d # => "Hello World!'
p a, b, c # (a b, c are not affected)
## => ["Hello World!", "World", "!"]

To add one or more strings to an existing string, use the concat method:

d = a.concat(b, c)
p d # => "Hello World!"
p a, b, c # (a has changed)
## => ["Hello World!", "World", "!"]

The shovel operator method << does the same, but one string at a time:

a, b, c = 'Hello ', 'World', '!'
d = a << b
p d # => "Hello World"
p a # => "Hello World" (a has changed)

To shovel multiple strings, do this: a << b << c.

Replace the first occurrence of a string:

p 'The Good The Bad The Ugly'.sub('The', 'THE')
## => "THE Good The Bad The Ugly"

Replace all occurrences:

p 'The Good The Bad The Ugly'.gsub('The', 'THE')
## => "THE Good THE Bad THE Ugly"

You can also use a regex pattern with sub and gsub:

p 'Good The Bad The'.gsub(/(\w+) (\w+)/, '\2 \1.')
## => "The Good. The Bad."

Trim whitespaces with the strip methods:

p "  spacious\t".strip # => "spacious"
p "  spacious\t".rstrip # => "  spacious"
p "  spacious\t".lstrip # => "spacious\t"

Remove trailing newlines with chomp. Useful when getting input from command line:

p "with newline\n".chomp # => "with newline"

You can insert a text into a string with insert:

p 'Feb 2025'.insert(3, 'ruary')
## => "February 2025"

You can also delete text within a string with delete:

p 'February 2025'.delete!('ruary') # => "Feb 2025"

Splitting and Joining a String

Split based on a character, a substring or a pattern with split:

p 'this is a    sentence'.split
## => ["this", "is", "a", "sentence"]
p 'col1,col2,col3'.split(',')
## => ["col1", "col2", "col3"]

Join an array of strings using a joining character with join:

p ['col1', 'col2', 'col3'].join(' | ')
## => "col1 | col2 | col3"

Mutable and Immutable Strings

From the way we’re manhandling the strings above, you probably realized by now that in Ruby they’re mutable.

But it’s nice to have immutable strings sometimes. Like when you have to be sure that the value you defined at the start of a program isn’t changed somewhere else down the line. Use freeze to make the string immutable.

secret_passphrase = 'this is such a secret'.freeze
## Somebody trying to change it!
secret_passphrase << 'changing suffix!' rescue nil
## => 💥 blows up with FrozenError without `rescue nil`.

Maybe you could check first if it is frozen? before trying to modify it:

p secret_passphrase.frozen? # => true

But I lied. You can still ‘mutate’ it by simply re-assigning a new string to the same variable(?!):

secret_passphrase = "muhaha"

So a better way is to assign these strings to Ruby constants.
They too can be re-assigned(!?), but you’ll at least get 2 warnings:

SECRET_PHRASE = 'real secret'.freeze
SECRET_PHRASE = 'changing'
## => warning: already initialized constant SECRET_PHRASE
## => warning: previous definition of SECRET_PHRASE was
## => here

(Ruby constants are just variables beginning with a capital letter, and defined outside a method or a function, with an intention by the programmer to not have its value changed after it is first defined.)

(Also, freeze is a method on the top-level Object class. So you can freeze anything in Ruby.)

Strings vs Characters

Strings are just group of characters. A single character is still an object of the String class.

p 'a'.class # => String

Use chars to get an array of characters from a string:

p 'neon'.chars # => ["n", "e", "o", "n"]

You can add longevity to your fingers by typing one character less when you define a character using the questionable quote:

p 'a' # => "a" (u typed 3 keys)
p ?a  # => "a" (u only typed 2 now!)

Encoding

By default ruby strings are UTF-8 encoded.

str = 'whoami'
p str.encoding.name # => "UTF-8"

You can change the encoding of all strings in a file by adding this comment as the first line in the file: # encoding: ASCII.

But if you only want to change a specific string’s encoding, then use the encode method:

str = str.encode('US-ASCII')
p str.encoding.name # => "US-ASCII"

Formatting String with Percent Literals

If you want to do C-style “sprintf” string formatting, you can do it with the elegant % operator method:

base_page_title = 'RubyExamples | %s and %d'
about_page = base_page_title % ['about', 4]
p about_page # => "RubyExamples | about and 4"

You can also use a hash for named substitutions:

base_page_title = 'RubyExamples | %{name} and %{num}'
contact_page = base_page_title % {name: 'contact', num: 5}
p contact_page # => "RubyExamples | contact and 5"

Lots of formatting options are available. See here.

Regular Expression Support

Ruby strings have great regex support with their match?, match and =~ methods that behave exactly like their Regexp counterparts.

p 'Vehicle number: AP34BX3439'.match?(/[A-Z]{2}\d{4}$/)
## => true
p 'silly' if 'silly' =~ /y$/ # => "silly"

Official Docs

  • String#unpack and its friend Array#pack are used for low-level string manipulation. Read this detailed guide.

Next topic: Symbols .