Ruby 字符串
字符串是编程里用得最多的数据类型。Ruby 的字符串功能非常丰富——单/双引号有明确分工、插值语法优雅、还有 heredoc、frozen 等特性。本章把字符串的常用操作过一遍,看完就能应付 90% 的日常需求。
1. 单引号 vs 双引号
这是 Ruby 字符串最基础也最常被忽略的区别。单引号几乎不解释,双引号会解释转义和插值:
# 单引号:几乎不解释,看到什么是什么
puts 'hello\nworld' # 字面输出 hello\nworld(反斜杠不转义)
puts 'It\'s me' # 唯一转义:用 \' 表示单引号本身
# 双引号:会解释转义序列与插值
puts "hello\nworld" # 真的换行输出
puts "tab\there" # 真的有制表符
puts "code: #{65}" # 输出 code: 65(支持任意表达式)
# 性能:单引号略快(不需要解析插值),不需要插值时优先用单引号记住这条:不需要插值就用单引号,需要插值或转义才用双引号。这是 Ruby 社区的性能与可读性约定。
2. 字符串插值(Ruby 最优雅特性之一)
双引号字符串里把表达式包进花括号(前面加井号)就能嵌入任意 Ruby 代码,远比其他语言的 + 拼接或 printf 优雅:
# 字符串插值:把任意 Ruby 表达式嵌入字符串
name = "Ruby"
puts "Hello, #{name}!" # Hello, Ruby!
# 插值里可以是任意表达式
puts "1 + 2 = #{1 + 2}" # 1 + 2 = 3
puts "现在时间: #{Time.now}"
puts "长度: #{name.length}"
# 调用方法
user = "alice"
puts "大写: #{user.upcase}" # 大写: ALICE
# 嵌套插值也行(但别滥用)
puts "Hi, #{"#{"nested"}"}" # Hi, nested3. heredoc:多行字符串
写 SQL、HTML 模板、长文本时,heredoc 是救星。Ruby 的 heredoc 有几种变体,常用的是 <<-(吃掉结尾缩进)和 <<~(自动去掉公共缩进,Ruby 2.3+):
# heredoc:多行字符串,常用于写 SQL、HTML 模板
sql = <<-SQL
SELECT * FROM users
WHERE age > 18
ORDER BY name
SQL
puts sql
# 输出三行原文,缩进被 <<- 的减号吃掉
# 普通版 <<~(波浪号,Ruby 2.3+):自动去掉公共缩进
text = <<~TEXT
第一行
第二行(缩进保留相对关系)
第三行
TEXT4. 常用方法(第一组:查找与替换)
Ruby 字符串方法多到记不完,下面是实战最常用的几组。先看长度、空白、大小写、查找替换:
s = " Hello, Ruby! "
# 长度与空判断
s.length # 17
s.size # 17(别名)
s.empty? # false
"".empty? # true
# 去空白
s.strip # "Hello, Ruby!"(两端去空白)
s.lstrip # 只去左
s.rstrip # 只去右
# 大小写
"abc".upcase # "ABC"
"ABC".downcase # "abc"
"hello".capitalize # "Hello"
"hello world".titleize # Rails 才有
# 查找与判断
s.include?("Ruby") # true
s.start_with?(" H") # true
s.end_with?("!")
# 替换
"hello".sub("l", "L") # "heLlo"(只替换第一个)
"hello".gsub("l", "L") # "heLLo"(全部)
"hello".gsub(/l+/, "L") # "heLo"(支持正则)一个高频面试题:sub 与 gsub 的区别——前者只替换第一个,后者替换所有。gsub 还支持正则,是做文本处理的利器。
5. 常用方法(第二组:分割、拼接、转换)
# 分割与拼接
"1,2,3,4".split(",") # ["1", "2", "3", "4"]
"a-b-c".split("-") # ["a", "b", "c"]
%w[a b c].join(",") # "a,b,c"
[1, 2, 3].join("-") # "1-2-3"
# 字符数组
"hello".chars # ["h", "e", "l", "l", "o"]
"hello".bytes # [104, 101, 108, 108, 111]
# 反转、重复
"hello".reverse # "olleh"
"ab" * 3 # "ababab"(乘法重复)
# 与数字互转
"42".to_i # 42
"3.14".to_f # 3.14
"42abc".to_i # 42(前缀解析)
"abc".to_i # 0(解析失败给 0)
42.to_s # "42"注意 split 返回数组,join 把数组拼回字符串,二者互为逆操作。字符串乘法 "ab" * 3 这种"语法糖"在 Ruby 里很常见,读起来像自然语言。
6. frozen string literal
Ruby 字符串默认可变,但每次修改都会创建新对象,影响性能。从 Ruby 2.3 开始,可以在文件首行加魔法注释,让该文件所有字符串字面量变成 frozen(不可变):
# frozen_string_literal:让字符串不可变
# 在文件第一行写魔法注释
# frozen_string_literal: true
# 之后该文件里所有字符串字面量都变成 frozen
s = "hello"
s << " world" # FrozenError: can't modify frozen String
# 单个字符串用 -e 后缀也能 frozen
s = "hello"frozen # 这种写法很少用
# 为什么要有这个?性能!
# Ruby 3.0 开始默认倾向 frozen,避免每次创建新对象这是社区为了提升性能引入的特性。新项目里都建议开启,Rails 7+ 默认开启。修改字符串时改用 += 或 ... 不可变方式。
7. 格式化与字面量语法
# 格式化:% 格式符(类似 C 的 sprintf)
puts "%s 有 %d 岁" % ["Alice", 30] # Alice 有 30 岁
puts "%.2f" % 3.14159 # 3.14
# sprintf 与 format 方法
sprintf("%05d", 42) # "00042"
format("%-10s|%10s", "name", "age") # 左右对齐
# %w 数组字面量:用空白分隔生成字符串数组
%w[apple banana cherry] # ["apple", "banana", "cherry"]
%w(apple banana) # 同上,分隔符可换
# %i 符号数组
%i[apple banana] # [:apple, :banana]%w 是实战超高频——写数组配置时省去一堆引号逗号。%i 是它的符号版。
小结
本章覆盖了字符串的日常操作。最该记住:单/双引号的区别、字符串插值语法、gsub 配正则、%w 字面量。下一篇看 Ruby 数组,把另一个核心集合类型讲透。
← 上一篇 Ruby 块与 yield
下一篇 Ruby 数组 →