पाठ 17 / 25

Strings, Regular Expressions and Encodings

Manipulate strings, use regular expressions and handle encodings.

Text processing

Ruby strings have a large method set: strip, squeeze, downcase/upcase/capitalize, start_with?/end_with?/include?, split, gsub/sub for replacement, tr for character translation, center/ljust/rjust for alignment, format (or %) for formatting, and heredocs (<<~TEXT) for multi-line strings with indentation stripped. Regular expressions are first-class: /\A\d{6}\z/ literals, =~ and match? for testing (match? is fastest when you do not need captures), match with named captures ((?<pin>\d{6})), scan to find all matches and gsub with a block for computed replacements. Use \A and \z to anchor to the whole string; ^ and $ match at line boundaries, a classic source of validation bugs. Strings carry an encoding, usually UTF-8; length counts characters, bytesize counts bytes, and force_encoding/encode handle data from other encodings. With # frozen_string_literal: true, build strings with interpolation or + rather than mutating literals.

Validation and extraction with regexes

Whole-string anchors, named captures and scan.

PIN = /\A\d{6}\z/
puts "411001".match?(PIN)                  # true
puts "411001\nhack".match?(/^\d{6}$/)      # true: ^ and $ match per line (unsafe for validation)
puts "411001\nhack".match?(PIN)            # false: \A and \z anchor the whole string

address = "12 MG Road, Pune 411001, Maharashtra"
if (m = address.match(/(?<city>[A-Z][a-z]+) (?<pin>\d{6})/))
  puts "#{m[:city]} - #{m[:pin]}"           # Pune - 411001
end

puts "Order o-12 and o-345 shipped".scan(/o-\d+/).inspect   # ["o-12", "o-345"]

masked = "Card 4242424242424242".gsub(/\d(?=\d{4})/, "*")  # mask all but the last 4 digits
puts masked

letter = <<~TEXT
  Dear #{"Asha"},
    Your order has shipped.
TEXT
puts letter

puts "नमस्ते".length, "नमस्ते".bytesize      # characters versus bytes

Use \A and \z for validation

Validating input with ^...$ lets strings with embedded newlines pass, a known source of injection bugs (and Rails warns about it in model validations). Anchor with \A and \z.

त्वरित जाँच: Which anchors match the start and end of the entire string in a Ruby regex?

  • ^ and $
  • \A and \z
  • < and >
  • \b and \B
Answer

\A and \z — ^ and $ match at line boundaries; \A and \z anchor the whole string.