正则表达式是描述文本模式的语言。在 Shell 中,grep、sed、awk 等工具都支持正则表达式,用于搜索、匹配、替换文本。掌握正则表达式,是文本处理的核心技能。
基本正则表达式(BRE)是 POSIX 标准的一部分,大多数工具都支持。
| 元字符 | 含义 |
|---|---|
. | 匹配任意单个字符 |
* | 匹配前一个字符 0 次或多次 |
^ | 匹配行首 |
$ | 匹配行尾 |
[] | 字符集合 |
[^] | 排除字符集合 |
\ | 转义字符 |
grep "a.c" file.txt
grep "ab*c" file.txt
grep "^hello" file.txt
grep "world$" file.txt
grep "[abc]" file.txt
grep "[0-9]" file.txt
grep "[^0-9]" file.txt
在基本正则中,量词需要转义:
| 量词 | 含义 |
|---|---|
\{n\} | 匹配前一个字符 n 次 |
\{n,\} | 匹配前一个字符至少 n 次 |
\{n,m\} | 匹配前一个字符 n 到 m 次 |
grep "a\{3\}" file.txt
grep "[0-9]\{3,5\}" file.txt
基本正则中分组需要转义:
grep "\(ab\)\{2\}" file.txt
匹配 "abab"。
扩展正则表达式(ERE)语法更简洁,不需要转义量词和分组。
grep -E "pattern" file.txt
egrep "pattern" file.txt
sed -r "s/pattern/replacement/" file.txt
awk '/pattern/' file.txt
| 量词 | 含义 |
|---|---|
+ | 匹配前一个字符 1 次或多次 |
? | 匹配前一个字符 0 次或 1 次 |
{n} | 匹配前一个字符 n 次 |
{n,} | 匹配前一个字符至少 n 次 |
{n,m} | 匹配前一个字符 n 到 m 次 |
grep -E "a+" file.txt
grep -E "a?" file.txt
grep -E "a{3}" file.txt
grep -E "a{2,5}" file.txt
grep -E "(ab)+" file.txt
grep -E "(a|b)" file.txt
| 表示或,(a|b) 匹配 a 或 b。
用 \1、\2 引用分组匹配的内容:
grep -E "(.)\1" file.txt
匹配连续两个相同的字符。
grep -E "([a-z]+) \1" file.txt
匹配重复的单词,如 "hello hello"。
grep -E "[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}" file.txt
grep -E "[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}" file.txt
更精确的匹配:
grep -E "([0-9]{1,3}\.){3}[0-9]{1,3}" file.txt
grep -E "[0-9]{4}-[0-9]{2}-[0-9]{2}" file.txt
grep -E "[0-9]{4}-(0[1-9]|1[0-2])-(0[1-9]|[12][0-9]|3[01])" file.txt
grep -E "1[3-9][0-9]{9}" file.txt
grep -E "https?://[a-zA-Z0-9.-]+[/a-zA-Z0-9._%+-]*" file.txt
POSIX 定义了字符类,更易读:
| 字符类 | 含义 |
|---|---|
[:alpha:] | 字母 |
[:digit:] | 数字 |
[:alnum:] | 字母和数字 |
[:space:] | 空白字符 |
[:punct:] | 标点符号 |
[:lower:] | 小写字母 |
[:upper:] | 大写字母 |
grep "[[:digit:]]" file.txt
grep "[[:alpha:]]" file.txt
grep "[[:space:]]" file.txt
sed -r 's/[0-9]+/NUMBER/g' file.txt
sed -r 's/([a-z]+)/[\1]/g' file.txt
sed -r 's/^[[:space:]]+//' file.txt
awk '/[0-9]+/' file.txt
awk '$1 ~ /^[a-z]+$/' file.txt
awk '$1 !~ /[0-9]/' file.txt
awk 'gsub(/[0-9]+/, "NUM")' file.txt
. 匹配任意字符,* 匹配 0 次或多次[] 字符集合,^ 行首,$ 行尾+ 匹配 1 次或多次,? 匹配 0 次或 1 次() 分组,| 或,\1 向后引用