Ruby 正则表达式

正则表达式(**Reg**ular **Ex**pression)是用于检查给定字符串是否与该模式匹配的模式。

在 Ruby 中,正则表达式模式定义在两个斜杠之间(`/pattern/`)。例如,

# A regex pattern
/^m.t$/       

上面的模式表示一个三字母字符串,其中:

  • `^` - 标记字符串的开始(此处,字符串以 `m` 开头)。
  • `.` - 表示任何一个字母或字符
  • `$` - 标记字符串的结束(此处,字符串以 `t` 结尾)。

例如,字符串如 `"mat"` 和 `"mit"` 匹配上述正则表达式模式。

然而,像 `"mom"` 和 `"magnet"` 这样的字符串不匹配,因为这些字符串不是以 `m` 开头并以 `t` 结尾的 **3** 个字母单词。


Ruby 正则表达式类

Ruby 提供了 `Regex` 类来处理正则表达式。您可以使用**字面量语法**或 `Regexp.new` 方法来创建正则表达式模式。

语法

# Using literal syntax
/pattern/

# Using Regexp.new
Regexp.new("pattern")

此处,`pattern` 是您想匹配的正则表达式模式。


Ruby 中的正则表达式标志

正则表达式标志会修改模式的解释方式。它们被添加到正则表达式的结束斜杠之后。

一些常用的标志是:

  • `i` - 大小写不敏感匹配
  • `m` - 多行模式

让我们看一个例子,

/^m/i

此模式匹配以 `"m"` 或 `"M"` 开头的字符串。


示例:Ruby 正则表达式

# A regular expression pattern for a five-letter word
# that starts with "a" and ends with "e"
pattern = /^a...e$/

# Test string
word = "apple"

# Check if the word matches the pattern if word.match?(pattern) puts "String matches the pattern"
else puts "String doesn't match the pattern" end

输出

String matches the pattern

在上面的示例中,我们检查了字符串 `"apple"` 是否与定义的正则表达式模式匹配。

模式 `"^a...e$"` 表示任何以 `a` 开头并以 `e` 结尾的五字母字符串。

这里,`match?` 方法如果在我们传递的字符串与正则表达式模式匹配时返回 `true`。

如果我们传递另一个字符串,如 `"apache"`,它不会与 `pattern` 匹配,因为 `"apache"` 的字符数超过五位。


元字符

为了指定正则表达式,需要使用元字符。元字符是正则表达式引擎以特殊方式解释的字符。

一些基本元字符是:

元字符 描述 示例
[] 指定您希望匹配的字符集。 /[abc]/
. 指定任何单个字符(换行符 `'\n'` 除外)。 /.../
^ 指定字符串以某个字符开头。 /^m/
$ 指定字符串以某个字符结尾。 /y$/
* 匹配前面元素的零次或多次出现。 /ca*t/
+ 匹配前面元素的一次或多次出现。 /ma+t/
? 匹配前面元素的零次或一次出现。 /ma?n/
{} 指定前面元素的重复次数范围。 /a{2}/
{} 用作 `或` 运算符。 /a|b/
() 对正则表达式中的子模式进行分组。 /(ab)+/

方括号:[]

``[]` 指定您希望匹配的字符集。例如,

/[abc]/

此模式匹配包含给定字符 `a`、`b` 或 `c` 中任何一个的字符串。

让我们检查以下字符串是否与正则表达式模式 `[abc]` 匹配。

字符串 匹配? 原因
“a” **1** 次匹配 字符串包含 `a`。
"ac" **2** 次匹配 字符串包含 `a` 和 `c`。
"jim" **0** 次匹配 字符串不包含 `a`、`b` 或 `c` 中的任何一个。
"abc" **3** 次匹配 字符串包含所有三个 - `a`、`b` 和 `c`。

**注意:** 您也可以使用方括号内的 `-` 来指定字符范围。例如,

  • [a-e][abcde] 相同。
  • ``[0-3]` 与 `[0123]` 相同。

句点

句点表示任何单个字符(换行符 `'\n'` 除外)。例如,

/.../

上述模式匹配任何三个字符的子字符串(换行符除外)。

让我们检查以下字符串是否与正则表达式模式 `...` 匹配,该模式表示三个字符的组合。

字符串 匹配? 原因
"abs" **1** 次匹配 字符串包含三个字母(`a`、`b`、`s`)。
"ac" **0** 次匹配 字符串不包含三个字母。
"jim" **1** 次匹配 字符串包含三个字母。
"abcd" **1** 次匹配 字符串包含四个字母,其中前三个将被视为匹配。
"abcjkl" **2** 次匹配 字符串包含六个字母(**3+3**)。

插入符号:^

插入符号 `^` 指定字符串以某个字符开头。例如,

/^m/

此模式匹配以字母 `"m"` 开头的字符串。

让我们检查以下字符串是否与正则表达式模式 `^m` 匹配。

字符串 匹配? 原因
"man" **1** 次匹配 它以 `"m"` 开头。
m **1** 次匹配 它以 `"m"` 开头。
Man **0** 次匹配 它不以 `"m"` 开头。
sms **0** 次匹配 它不以 `"m"` 开头。

美元符号:$

美元符号 `$` 指定字符串以某个字符结尾。例如,

/y$/

此模式匹配以字母 `"y"` 结尾的字符串。

让我们检查以下字符串是否与正则表达式模式 `y$` 匹配。

字符串 匹配? 原因
"monday" **1** 次匹配 它以 `"y"` 结尾。
"say" **1** 次匹配 它以 `"y"` 结尾。
"myname" **0** 次匹配 它不以 `"y"` 结尾。

星号:*

星号 `*` 匹配前面元素的零次或多次出现。例如,

/ca*t/

这里,`a` 是 `*` 前面的元素。因此,此模式匹配 `c` 和 `t` 之间包含任意数量(包括零个)`a` 的字符串。

让我们检查以下字符串是否与正则表达式模式 `ca*t` 匹配。

字符串 匹配? 原因
"cat" **1** 次匹配 它在 `c` 和 `t` 之间有一个 `a`。
"ct" **1** 次匹配 它在 `c` 和 `t` 之间没有 `a`。
"caaaat" **1** 次匹配 它在 `c` 和 `t` 之间有三个 `a`。
"crt" **0** 次匹配 它在 `c` 和 `t` 之间是字母 `r`(不是 `a`)。
"caatcaaat" **2** 次匹配 它在两个地方包含 `a`(`caat` 和 `caaat`)。

加号:+

加号 `+` 匹配前面元素的一次或多次出现。例如,

/ma+t/

此模式匹配 `m` 和 `t` 之间包含一个或多个 `a` 的字符串。

让我们检查以下字符串是否与正则表达式模式 `ma+t` 匹配。

字符串 匹配? 原因
"mat" **1** 次匹配 它在 `m` 和 `t` 之间有一个 `a`。
"mt" **0** 次匹配 它在 `m` 和 `t` 之间没有 `a`。
"matemaat" **2** 次匹配 它有两个匹配的子字符串(`mat` 和 `maat`)。
"mart" **0** 次匹配 `mart` 中的 `r` 后面没有 `t`。

问号:?

问号 `?` 匹配前面元素的零次或一次出现。例如,

/ma?n/

此模式匹配 `m` 和 `n` 之间包含一个或零个 `a` 的字符串。

让我们检查以下字符串是否与正则表达式模式 `ma?n` 匹配。

字符串 匹配? 原因
"man" **1** 次匹配 它在 `m` 和 `n` 之间有一个 `a`。
"mn" **1** 次匹配 它在 `m` 和 `n` 之间有零个 `a`。
"maaaaan" **0** 次匹配 它在 `m` 和 `n` 之间有多个 `a`。
"woman" **1** 次匹配 它在 `m` 和 `n` 之间有一个 `a`。

花括号:{}

花括号 ` {} ` 用于指定前面元素的重复次数范围。

/a{2}/

此模式匹配连续两个 `a` 字符的字符串。

花括号 ` {} ` 可以用作:

# Exactly n times
{n}

# At least n times
{n,}

# Between n and m times
{n, m}

让我们检查以下字符串示例是否与正则表达式模式 `/a{2}/` 匹配。

字符串 匹配? 原因
"aa" **1** 次匹配 它包含连续的两个 `a`。
"abcdaat" **1** 次匹配 它在其他字符的左侧有两个 `a`。

交替:|

竖线 `|` 用作 `或` 运算符。例如,

/a|b/

此模式匹配包含 `a` 或 `b` 的字符串。

让我们检查以下字符串是否与正则表达式模式 `a|b` 匹配。

字符串 匹配? 原因
"cde" **0** 次匹配 它不包含 `a` 或 `b`。
"ade" **1** 次匹配 字符串中有一个 `a`。
"acdbea" **3** 次匹配 匹配字符串中的每个单独的 `a` 或 `b`。

括号:()

括号 ` () ` 用于对正则表达式中的子模式进行分组。

分组允许您将量词(如 `+`、`*` 或 `{}`)应用于整个组。例如,

/(ab)+/

此模式匹配子字符串 `"ab"` 的一次或多次出现。

让我们检查以下字符串是否与正则表达式模式 `(ab)+` 匹配。

字符串 匹配? 原因
"ab" **1** 次匹配 它包含一次 `"ab"` 的出现。
"abab" **1** 次匹配 它有两个连续的 `"ab"` 序列。
"ababab" **1** 次匹配 它有三个连续的 `"ab"` 序列的单个长匹配。
"aabb" **0** 次匹配 `"aa"` 打破了有效的重复组。

特殊序列

Ruby 正则表达式也支持常用字符集的特殊序列。

模式 描述
\d 任何数字(等同于 `[0-9]`)
\D 任何非数字
\w 单词字符(字母、数字、下划线)
\W 非单词字符
\s 空白字符
\S 非空白字符

示例:匹配数字

`\d` 序列 ****在指定字符是一个或多个数字时匹配。例如,

/\d+/

此模式匹配一个或多个数字。

让我们检查以下字符串示例是否与正则表达式模式 `\d+` 匹配。

字符串 匹配? 原因
"123" **1** 次匹配 字符串完全由数字组成,这些数字被组合在一起作为一个数字计数。
"a1b2c3" **3** 次匹配 分别匹配 **1**、**2** 和 **3**,因为它们之间有字母字符。
"abc" **0** 次匹配 没有数字。

转义序列

如果要匹配特殊字符(如 `.` 或 `*`),则需要使用反斜杠 `\` 对其进行转义。例如,

/\./

这匹配一个字面上的句点 `.`。

让我们检查以下字符串是否与正则表达式模式 `\.` 匹配。

字符串 匹配? 原因
"hello." **1** 次匹配 匹配字符串末尾存在的句点字符。
"hello" **0** 次匹配 没有句点。
"hi.." **2** 次匹配 匹配了两个字面上的句点。

Regex 方法

Ruby 提供了几种处理正则表达式的方法。

方法 描述
=~ 返回第一个匹配的索引或 `nil`。
匹配 返回 `MatchData` 对象或 `nil`。
match? (>= 2.4) 如果找到匹配项则返回 `true`,否则返回 `false`。
scan 返回所有匹配的子字符串的数组。
gsub 替换所有匹配项。

示例:使用正则表达式方法

text = "I have 2 cats and 3 dogs"

# Find first match
# Output: 7
puts text =~ /\d/

# Get all digits
# Output: 2, 3
puts text.scan(/\d/).join(", ")

# Replace digits with '#'
# Output: I have # cats and # dogs
puts text.gsub(/\d/, '#')

正则表达式的用例

正则表达式常用于实际编程任务,例如:

  • 验证输入格式(例如,电子邮件、电话号码)。
  • 在文本中搜索特定关键字。
  • 提取字符串的一部分(例如,数字、单词)。
  • 将匹配的模式替换为新值。
你觉得这篇文章有帮助吗?

我们的高级学习平台,凭借十多年的经验和数千条反馈创建。

以前所未有的方式学习和提高您的编程技能。

试用 Programiz PRO
  • 交互式课程
  • 证书
  • AI 帮助
  • 2000+ 挑战