简介
本教程将向你介绍 Bash 中的正则表达式(regex)。正则表达式是用于在文本中查找模式的强大工具。通过学习正则表达式,你将大大提高你的 shell 脚本编写技能,从而能够更有效地处理文本、提取数据和自动化任务。本教程专为初学者设计,因此无需具备正则表达式的先验经验。我们将从基础开始,逐步积累你的知识。
本教程将向你介绍 Bash 中的正则表达式(regex)。正则表达式是用于在文本中查找模式的强大工具。通过学习正则表达式,你将大大提高你的 shell 脚本编写技能,从而能够更有效地处理文本、提取数据和自动化任务。本教程专为初学者设计,因此无需具备正则表达式的先验经验。我们将从基础开始,逐步积累你的知识。
让我们从正则表达式的基本概念开始。正则表达式是定义一个 搜索模式 的字符序列。你可以把它看作是一种非常强大的文本搜索方式。
以下是基本的构建块:
abc
将精确匹配字符串 "abc"。.
(点):匹配 任意单个字符(换行符除外)。因此,a.c
可以匹配 "abc"、"axc"、"a1c" 等等。*
(星号):匹配 前一个字符零次或多次。ab*c
可以匹配 "ac"、"abc"、"abbc"、"abbbc" 等。^
(脱字符):匹配 行的开头。^hello
将匹配以 "hello" 开头的行。$
(美元符号):匹配 行的结尾。world$
将匹配以 "world" 结尾的行。[]
(方括号):定义一个 字符类。它匹配方括号内的 任意一个 字符。[abc]
可以匹配 "a"、"b" 或 "c"。[0-9]
匹配任意单个数字。现在,让我们创建一个 Bash 脚本来测试我们的理解。使用 touch
命令创建一个名为 regex_test.sh
的文件:
cd ~/project
touch regex_test.sh
接下来,使用文本编辑器(如 nano
或 vim
)打开 regex_test.sh
并添加以下代码:
#!/bin/bash
string="Hello World"
if [[ "$string" =~ ^Hello ]]; then
echo "The string starts with Hello"
else
echo "The string does not start with Hello"
fi
保存文件并使其可执行:
chmod +x regex_test.sh
最后,运行脚本:
./regex_test.sh
输出应该表明该字符串以 "Hello" 开头。
使用方括号 []
定义的字符集允许你从特定组中匹配一个字符。这对于创建更灵活的模式非常有用。
[]
内,你可以使用连字符 (-
) 来指定一个范围。[a-z]
匹配任何小写字母,[A-Z]
匹配任何大写字母,[0-9]
匹配任何数字。你可以将它们组合起来:[a-zA-Z0-9]
匹配任何字母数字字符。^
作为 []
内的 第一个 字符,它会对该字符类进行 取反。[^0-9]
匹配任何 非 数字字符。让我们修改我们的 regex_test.sh
脚本以使用字符集。使用文本编辑器打开 regex_test.sh
并将其内容替换为以下内容:
#!/bin/bash
string="cat"
if [[ "$string" =~ c[a-z]t ]]; then
echo "Match found!"
else
echo "No match."
fi
保存文件并运行它:
./regex_test.sh
输出应该显示 "Match found!"。这是因为 c[a-z]t
匹配任何以 'c' 开头、以 't' 结尾的三个字母的字符串,其中中间字符是小写字母。
量词用于控制一个字符或字符组应该重复的次数。这极大地增强了你的正则表达式模式的功能。
+
(加号):匹配前一个字符 一次或多次。ab+c
可以匹配 "abc"、"abbc"、"abbbc" 等,但 不 匹配 "ac"。?
(问号):匹配前一个字符 零次或一次(即让前一个字符可选)。ab?c
可以匹配 "ac" 和 "abc",但不匹配 "abbc"。*
(星号):匹配前一个字符 零次或多次。我们之前已经见过这个。{n}
:精确匹配前一个字符 n 次。a{3}
匹配 "aaa"。{n,}
:匹配前一个字符 n 次或更多次。a{2,}
匹配 "aa"、"aaa"、"aaaa" 等。{n,m}
:匹配前一个字符 n 到 m 次(包含 n 和 m)。a{1,3}
匹配 "a"、"aa" 或 "aaa"。让我们修改 regex_test.sh
脚本以使用量词。用文本编辑器打开 regex_test.sh
并将其内容替换为以下代码:
#!/bin/bash
string="abbbc"
if [[ "$string" =~ ab+c ]]; then
echo "Match found!"
else
echo "No match."
fi
保存文件并运行它:
./regex_test.sh
输出应该显示 "Match found!"。这是因为 ab+c
匹配以 'a' 开头,后面跟着一个或多个 'b',并以 'c' 结尾的字符串。
括号 ()
用于对正则表达式的部分进行 分组。这对于将量词应用于多个字符以及 捕获 匹配的文本非常有用。
当你使用括号时,Bash 会将正则表达式中该部分匹配的文本存储在一个名为 BASH_REMATCH
的特殊数组中。BASH_REMATCH[0]
包含整个匹配的字符串,BASH_REMATCH[1]
包含第一个捕获组匹配的文本,BASH_REMATCH[2]
包含第二个捕获组匹配的文本,依此类推。
让我们修改 regex_test.sh
脚本,使用捕获组来提取数据。用文本编辑器打开 regex_test.sh
,并将其内容替换为以下代码:
#!/bin/bash
string="apple123"
if [[ "$string" =~ ^([a-z]+)([0-9]+)$ ]]; then
fruit="${BASH_REMATCH[1]}"
number="${BASH_REMATCH[2]}"
echo "Fruit: $fruit"
else
echo "No match."
fi
保存文件并运行它:
./regex_test.sh
输出应该包含 "Fruit: apple"。此脚本使用捕获组从字符串中提取水果名称。
sed
替换文本让我们创建一个名为 sed_test.sh
的新脚本,来练习使用 sed
。
cd ~/project
touch sed_test.sh
chmod +x sed_test.sh
用文本编辑器打开 sed_test.sh
并添加以下内容:
#!/bin/bash
string="apple123"
echo "$string" | sed 's/[0-9]/X/g'
保存文件并运行它:
./sed_test.sh
输出应该是:appleXXX
。此脚本使用 sed
将字符串中的所有数字替换为字母 "X"。
本教程向你介绍了 Bash 中的正则表达式(regex)。你学习了基本的正则表达式概念、字符类、量词、分组、捕获,以及如何将正则表达式与 sed
结合使用。通过编写和执行 Bash 脚本,你已经获得了使用这些强大工具的实践经验。请记住通过练习和尝试不同的正则表达式模式来巩固你的理解。