4

Text Processing and Structured Input

Ruby source files are converted directly from the English source tree.

en/topic_04_strings_symbols_ranges_regex

Overview

Why this topic matters ๐Ÿ’ก

A large amount of real software work is text work: validating input, normalizing strings, turning labels into URLs, and working with structured keys. Ruby is strong here because strings and regular expressions are practical, accessible tools.

Learning outcomes ๐ŸŽฏ

By the end of this topic, students should be able to:

  • explain the role of symbols as lightweight identifiers;
  • use ranges to model inclusive sequences clearly;
  • use regular expressions for straightforward validation tasks;
  • normalize text safely for simple URL-friendly output;
  • explain the boundary between useful regex and overcomplicated regex.

Assessment focus โœ…

Students should be able to solve ordinary text problems clearly without turning the code into unreadable pattern magic.

Short Note

Ruby often feels pleasant when code needs to shape, clean, and validate strings. That does not mean every text problem should become clever. The educational target is practical string handling with readable intent.

Students should notice that:

  • ranges communicate inclusive spans naturally;
  • regex can express common validation succinctly;
  • a little text normalization goes a long way in web-style code;
  • symbols often make hashes feel cleaner when keys are stable identifiers.

Ruby beauty in this topic:

  • simple string pipelines read naturally;
  • regex support is built into ordinary Ruby code;
  • short transformations can still express business purpose clearly.

Ruby caution in this topic:

  • regex can become write-only code if overused;
  • text cleanup rules need explicit boundaries or they become inconsistent.

Reflection prompt:

  • When is a regex a clear solution, and when is it a maintenance burden?

Worked Examples

Example 1: Validating common user input ๐Ÿ’ก

Email validation is a useful teaching case because teams do it constantly, but a course exercise can keep the rule intentionally modest.

The lesson is not "build perfect email validation." The lesson is "use regex for a reasonable local rule and know its limits."

Example 2: Generating URL slugs ๐Ÿ’ก

Slugification is a realistic example from blogs, CMS systems, and admin tools.

slugifier.slugify("Ruby for Java Developers")
# => "ruby-for-java-developers"
worked_examples.md
ruby

Why this is useful:

  • the transformation is visible step by step;
  • the result is meaningful in web applications;
  • the code demonstrates Ruby's strength in short text pipelines.

Cheatsheet

Range

(1..5).to_a
cheatsheet.md
ruby

Email-style regex

EMAIL_REGEX = /\A[^\s@]+@[^\s@]+\.[^\s@]+\z/
cheatsheet.md
ruby

Slug pipeline

text.downcase.strip
    .gsub(/\s+/, "-")
    .gsub(/[^a-z0-9-]/, "")
cheatsheet.md
ruby

Key reminders

  • \A and \z anchor the whole string.
  • .. is inclusive range syntax.
  • Prefer readable regex for common validation only.

Study Guide

Topic purpose ๐ŸŽฏ

Learn how Ruby handles ordinary text-heavy tasks cleanly. The emphasis is practical string work, not showing off regex complexity.

Study sequence ๐Ÿชœ

  1. Read overview.md.
  2. Read shortnote.md and note where regex should remain modest.
  3. Study worked_examples.md.
  4. Use cheatsheet.md while reading example.rb.
  5. Complete the range exercise.
  6. Complete the slug exercise and explain each transformation step.

What to notice ๐Ÿ”Ž

  • Range syntax is compact but readable.
  • Regex is best used for simple local validation rules.
  • A transformation pipeline should still be explainable line by line.

Reflection questions ๐Ÿค”

  • Why is the slug example more educational than a purely synthetic string exercise?
  • What would make the regex approach too brittle for production use?
  • When should symbol keys be preferred over free-form strings?

Source Files and Tests

Ruby source files are converted directly from the English source tree.

# EXAMPLE CODE
# Topic: topic_04_strings_symbols_ranges_regex
#
# Purpose:
# - This file demonstrates reference implementation for the concept.
# - It should pass tests from the beginning.
# - Read and understand it before solving exercises.

class Validator
  EMAIL_REGEX = /\A[^\s@]+@[^\s@]+\.[^\s@]+\z/

  def valid_email?(value)
    !!(value =~ EMAIL_REGEX)
  end
end
en/topic_04_strings_symbols_ranges_regex/example.rb
Ruby course source
# STUDENT TASK (BASIC)
# Topic: topic_04_strings_symbols_ranges_regex
#
# What to do:
# - Implement or improve the class/methods in this file.
# - Read tests in tests/topic_04_strings_symbols_ranges_regex_spec.rb under the "basic exercise" examples.
# - Make tests pass without breaking the example/advanced sections.
#
# Expected outcome:
# - You can run this topic tests and see all examples green after implementation.

class RangeBuilder
  def inclusive(a, b)
    (a..b).to_a
  end
end
en/topic_04_strings_symbols_ranges_regex/basic_exercise.rb
Ruby course source
# STUDENT TASK (ADVANCED)
# Topic: topic_04_strings_symbols_ranges_regex
#
# Academic purpose:
# - Practice a realistic text-normalization task rather than isolated string syntax.
# - Learn how Ruby can express a multi-step text transformation compactly and readably.
#
# Real-world use case:
# - Slugs appear in blog platforms, CMS tools, documentation systems, and admin panels.
# - Teams use them to convert human-readable titles into URL-friendly identifiers.
# - This is exactly the sort of small but common feature where Ruby feels elegant.
#
# Why Ruby is beautiful here:
# - String methods chain naturally.
# - Each transformation step reflects a concrete formatting decision.
# - The code is short enough to scan but still close to the product need.
#
# What to do:
# - Complete the challenge behavior requested by the guide.
# - Be able to explain what each `gsub` removes or reshapes.
# - Use tests in tests/topic_04_strings_symbols_ranges_regex_spec.rb under the "advanced exercise" examples.
#
# Expected outcome:
# - Advanced tests pass and you can connect the implementation to a web-facing use case.

class Slugifier
  def slugify(text)
    text.downcase.strip.gsub(/\s+/, "-").gsub(/[^a-z0-9-]/, "")
  end
end
en/topic_04_strings_symbols_ranges_regex/adv_exercise.rb
Ruby course source
# ANSWER KEY (BASIC)
# Topic: topic_04_strings_symbols_ranges_regex
#
# Solution idea:
# - Ruby ranges are inclusive with `..`.
# - Convert the range to an array because the tests want the concrete sequence.

class RangeBuilder
  def inclusive(a, b)
    (a..b).to_a
  end
end
en/topic_04_strings_symbols_ranges_regex/answer_basic_exercise.rb
Ruby course source
# ANSWER KEY (ADVANCED)
# Topic: topic_04_strings_symbols_ranges_regex
#
# Solution idea:
# - Normalize case first.
# - Remove surrounding whitespace.
# - Collapse internal whitespace into hyphens.
# - Strip any remaining characters that are not slug-safe for this exercise.

class Slugifier
  def slugify(text)
    text.downcase.strip.gsub(/\s+/, "-").gsub(/[^a-z0-9-]/, "")
  end
end
en/topic_04_strings_symbols_ranges_regex/answer_adv_exercise.rb
Ruby course source
# This spec is your learning companion for topic_04_strings_symbols_ranges_regex.
#
# How to use this file:
# 1) Run tests and observe failures/successes.
# 2) Keep EXAMPLE specs green from the beginning.
# 3) Implement BASIC exercise until BASIC specs pass.
# 4) Implement ADVANCED exercise and pass edge cases.
#
# Expected final result:
# - All examples in this file pass.
# - You understand both the concept and the implementation tradeoffs.

require_relative "../example"
require_relative "../basic_exercise"
require_relative "../adv_exercise"

RSpec.describe "topic_04_strings_symbols_ranges_regex" do
  describe "EXAMPLE purpose: understand the reference implementation" do
      it "validates email formats" do
        v = Validator.new
        expect(v.valid_email?("a@b.com")).to eq(true)
        expect(v.valid_email?("x y@z.com")).to eq(false)
      end
  end

  describe "BASIC EXERCISE purpose: implement the comparable task" do
      it "creates inclusive ranges" do
        expect(RangeBuilder.new.inclusive(1, 3)).to eq([1, 2, 3])
      end
  end

  describe "ADVANCED EXERCISE purpose: solve challenge and edge cases" do
      it "slugifies text" do
        expect(Slugifier.new.slugify(" Hello Ruby 3.4! ")).to eq("hello-ruby-34")
      end
  end
end
en/topic_04_strings_symbols_ranges_regex/tests/topic_04_strings_symbols_ranges_regex_spec.rb
Ruby course source
#!/usr/bin/env bash
set -euo pipefail

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
ROOT_DIR="$(cd "${SCRIPT_DIR}/.." && pwd)"

exec "${ROOT_DIR}/run_tests.sh" "$(basename "${SCRIPT_DIR}")"
en/topic_04_strings_symbols_ranges_regex/run_topic_tests.sh
Ruby course source

Study Prompts

  1. Read the spec first and identify which behaviors belong to the example, basic exercise, and advanced exercise.

  2. Attempt the exercises before opening the answer files, then compare the design choices.