正则表达式
在 Linux 中是一个非常强大的工具,适用于各种文本处理任务。掌握基本和扩展正则表达式的语法,可以高效地完成复杂的文本搜索、匹配和替换任务。无论是在命令行 还是在脚本中,grep
、sed
、awk
、vi/vim
等。
基本正则表达式(BRE)
常用符号
.
- 匹配任意单个字符
grep 'a.b' file.txt
# 匹配 a 后面跟一个任意字符,再跟一个 b 的所有行,如 acb、aab
^
- 匹配行首
grep '^start' file.txt
# 匹配以 start 开头的所有行。
$
- 匹配行尾
grep 'end$' file.txt
# 匹配以 end 结尾的所有行
*
- 匹配前一个字符的零次或多次出现
grep 'fo*' file.txt
# 匹配 f 后面跟零个或多个 o 的所有行,如 f、fo、foo
[]
- 匹配字符类中的任意单个字符
grep '[abc]' file.txt
# 匹配方括号内的任意一个字符(a、b或c)
[^]
- 匹配不在字符类中的任意单个字符
grep '[^abc]' file.txt
# 匹配除了方括号内的任意一个字符(除了a、b或c)
\
- 转义字符,用于转义元字符
grep '\.' file.txt
# 匹配实际的点 . 字符,而不是任意字符
\{m,n\}
- 匹配前一个字符的至少 m 次,至多 n 次出现
grep 'o\{2,4\}' file.txt
# 匹配包含 oo、ooo 或 oooo 的所有行
扩展正则表达式(ERE)
使用 grep -E
、egrep
或 sed -E
时,可以使用扩展正则表达式(ERE),支持更多的元字符和语法
+
: 匹配前一个字符的一次或多次
出现
grep -E 'fo+' file.txt
- 匹配 f 后面跟一个或多个 o 的所有行,如 fo、foo。
?
: 匹配前一个字符的零次或一次
出现
grep -E 'fo?' file.txt
- 匹配 f 后面跟零个或一个 o 的所有行,如 f、fo。
|
: 逻辑或,匹配左边或右边的模式
grep -E 'foo|bar' file.txt
- 匹配包含 foo 或 bar 的所有行。
()
: 分组,用于将多个字符组合为一个单元
grep -E '(foo|bar)baz' file.txt
- 匹配 foobaz 或 barbaz。
{m,n}
: 匹配前一个字符的至少 m 次
,至多 n 次
出现(无需转义)
grep -E 'o{2,4}' file.txt
- 匹配包含 oo、ooo 或 oooo 的所有行。
正则表达式的高级用法
零宽度断言:零宽度断言(lookahead 和 lookbehind)是匹配过程中的一部分,但不消耗字符。
- 正向前瞻(Lookahead)
grep -P 'foo(?=bar)' file.txt
- 匹配 foo,但只有当其后紧跟 bar 时才匹配。
- 负向前瞻(Negative Lookahead)
grep -P 'foo(?!bar)' file.txt
- 匹配 foo,但只有当其后不是 bar 时才匹配。
- 正向后顾(Lookbehind)
grep -P '(?<=foo)bar' file.txt
- 匹配 bar,但只有当其前面是 foo 时才匹配
- 负向后顾(Negative Lookbehind)
grep -P '(?<!foo)bar' file.txt
- 匹配 bar,但只有当其前面不是 foo 时才匹配。
捕获组与反向引用:捕获组用于分组模式,反向引用可以在匹配时重新引用这些捕获的内容。
grep -E '([0-9]{3})-\1' file.txt
- 匹配形如 123-123 的模式,其中 \1 表示前面捕获的第一个组。
应用示例
- 匹配邮箱地址
grep -E '[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}' file.txt
- 匹配IP地址
grep -E '\b([0-9]{1,3}\.){3}[0-9]{1,3}\b' file.txt
- 匹配电话号码
grep -E '\b[0-9]{3}-[0-9]{3}-[0-9]{4}\b' file.txt
总结
-
基本字符匹配:
.
匹配任意单个字符(除了换行符)。^
匹配输入字符串的开始位置。$
匹配输入字符串的结束位置。
-
字符类:
[abc]
匹配方括号内的任意一个字符(a、b或c)。[^abc]
匹配除了方括号内的任意一个字符(除了a、b或c)。[a-zA-Z]
匹配所有大小写字母。
-
预定义字符类:
\d
匹配任意数字,等同于[0-9]
。\w
匹配任意字母数字字符,包括下划线。\s
匹配任意的空白符。
-
量词:
*
匹配前面的子表达式零次或多次。+
匹配前面的子表达式一次或多次。?
匹配前面的子表达式零次或一次。{n}
匹配确定的n次。{n,}
至少匹配n次。{n,m}
匹配n到m次。
-
分组和捕获:
()
创建一个组,并捕获匹配的文本。
-
选择和分支:
|
逻辑或操作符,匹配两个表达式中的任意一个。
-
特殊字符的转义:
\
用于转义特殊字符,使其失去特殊含义,只作为普通字符匹配。
-
扩展标志:
i
忽略大小写。g
全局搜索,不停止在第一个匹配项。