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"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_aruby
Email-style regex
EMAIL_REGEX = /\A[^\s@]+@[^\s@]+\.[^\s@]+\z/ruby
Slug pipeline
text.downcase.strip
.gsub(/\s+/, "-")
.gsub(/[^a-z0-9-]/, "")ruby
Key reminders
\Aand\zanchor 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 ๐ช
- Read
overview.md. - Read
shortnote.mdand note where regex should remain modest. - Study
worked_examples.md. - Use
cheatsheet.mdwhile readingexample.rb. - Complete the range exercise.
- 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
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
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
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
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
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
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}")"
Ruby course source
Study Prompts
Read the spec first and identify which behaviors belong to the example, basic exercise, and advanced exercise.
Attempt the exercises before opening the answer files, then compare the design choices.