了解POSIX基本正则表达式
本文将介绍基本正则表达式。
Linux最常见的表达式有三种:
-
POSIX基本正则表达式;
-
POSIX扩展正则表达式 ;
-
Perl 兼容正则表达式。
本文将简单介绍POSIX基本正则表达式。
什么是POSIX基本正则表达式
POSIX基本正则表达式,也称BRE (Basic Regular Expression) ,是POSIX标准中的一种正则表达式,在Linux 中,grep、sed、awk等工具都支持该基本正则表达式。
BRE特点
基本正则表达式语法相对而言较为简单,适用于大多数基本的文本匹配。
支持的元字符
| 元字符 |
用途 |
| . |
匹配除换行符以外的任意单个字符 |
| * |
匹配任意个(包括0个)前面的字符 |
| [...] |
匹配方括号中的字符集中的任何一个 |
| [^...] |
如果方括号中第一个字符是^,则表示否定匹配 |
| ^ |
如果作为正则第一个字符,则表示匹配行起始 |
| $ |
如果作为正则最后一个字符,则表示匹配行的结尾 |
| \{n\} |
将匹配n次出现 |
| \{n,m\} |
匹配它前一个范围内单个字符出现的次数,匹配n次m次之前的任意次数 |
| \ |
转义特殊字符 |
支持的转义字符
| 转义字符 |
用途 |
| \. |
匹配字面意思的点. |
| \\ |
匹配字面意思的反斜杠\ |
| \* |
匹配字面意思的星号* |
支持的字符集
| 字符集 |
用途 |
| [abc] |
匹配a、b、c 中的任意字符 |
| [0-9] |
匹配任意数字,同理[a-z]匹配任意小写字符、[A-Z]匹配任意大写字符 |
| [^abc] |
匹配不包含a、b、c 的任意字符 |
支持的字符类
| 字符类 |
用途 |
| [:alnum:] |
可打印的字符 |
| [:alpha:] |
字母字符 |
| [:blank:] |
空格和制表符 |
| [:cntrl:] |
控制字符 |
| [:digit:] |
数字字符 |
| [:graph:] |
可打印的和可见的字符 |
| [:lower:] |
小写字符 |
| [:print:] |
可打印的字符 |
| [:punct:] |
标点符号字符 |
| [:space:] |
空白字符 |
| [:upper:] |
大写字符 |
| [:xdigit:] |
十六进制数字 |
支持的分组操作
元字符操作
. 可以匹配任意字符
| Bash |
|---|
| root@debian:~# echo '123' | grep '1.3'
123
root@debian:~#
|
. 可以匹配任何字符,但是不包括换行符\n。
但是无法匹配换行符
| Bash |
|---|
| root@debian:~# echo -e '1\n2\n3' > hello
root@debian:~#
root@debian:~# cat hello -A
1$
2$
3$
root@debian:~#
root@debian:~# grep '1.2' hello
root@debian:~#
|
* 匹配任意个前面的字符
| Bash |
|---|
| root@debian:~# echo "abbbbbbbbbd" | grep 'a*d'
abbbbbbbbbd
root@debian:~#
|
* 匹配上面任意字符0 次或者无数次。
| Bash |
|---|
| root@debian:~# echo "1" | grep ' *'
1
root@debian:~#
|
上面案例之所以能够被匹配到是因为
可以和*一起使用,表示匹配任意字符
| Bash |
|---|
| root@debian:~# echo "abced" | grep 'a.*e'
abced
root@debian:~#
|
^匹配起始行
| Bash |
|---|
| root@debian:~# echo "abced" | grep '^a'
abced
root@debian:~#
root@debian:~# echo "baced" | grep '^a'
root@debian:~#
|
$匹配行结尾
| Bash |
|---|
| root@debian:~# echo 'abced' | grep 'd$'
abced
root@debian:~# echo 'abcede' | grep 'd$'
root@debian:~#
|
可以和^ 搭配使用,表示匹配空行
| Bash |
|---|
| root@debian:~# echo '' | grep '^$'
root@debian:~#
|
匹配上一个字符出现的次数
| Bash |
|---|
| root@debian:~# echo 'abbbc' | grep 'ab\{3\}c'
abbbc
root@debian:~#
|
注意,在基本正则表达式中,{} 必须使用\ 进行转义,如直接使用时不行的。
| Bash |
|---|
| root@debian:~# echo 'abbbc' | grep 'ab{3}c'
root@debian:~#
|
如果不加\进行转义,是直接匹配{}字符,而非正则表达式。
| Bash |
|---|
| root@debian:~# echo 'ab{3}c' | grep 'ab{3}c'
ab{3}c
root@debian:~#
|
匹配上一个出现的次数范围
| Bash |
|---|
| root@debian:~# echo "abbbc" | grep 'ab\{3,5\}c'
abbbc
root@debian:~# echo "abbbc" | grep 'ab\{4,5\}c'
root@debian:~#
|
转义特殊字符
| Bash |
|---|
| root@debian:~# echo "a\.e" | grep 'a\\.e'
a\.e
root@debian:~#
|
. 、* 、^、$都需要进行转义。
字符集操作
匹配范围内的任意字符
| Bash |
|---|
| root@debian:~# echo 'a2c' | grep 'a[123]c'
a2c
root@debian:~#
|
匹配字符范围
| Bash |
|---|
| root@debian:~# echo "3" | grep '[1-9]'
3
root@debian:~#
root@debian:~# echo "a" | grep '[a-z]'
a
root@debian:~#
root@debian:~# echo "a" | grep '[a-z]'
a
root@debian:~#
root@debian:~# echo "Z" | grep '[a-Z]'
Z
root@debian:~#
|
字符类操作
匹配数字字符
| Bash |
|---|
| root@debian:~# echo '13579' | grep '[[:digit:]]'
13579
root@debian:~#
|
匹配小写字母
| Bash |
|---|
| root@debian:~# echo 'abcde' | grep '[[:lower:]]'
abcde
root@debian:~#
|
匹配大写字母
| Bash |
|---|
| root@debian:~# echo 'ABCDE' | grep '[[:upper:]]'
ABCDE
root@debian:~#
|
匹配空白字符
| Bash |
|---|
| root@debian:~# echo " " | grep '[[:space:]]'
root@debian:~#
|
分组操作
分组是指使用小括号将表达式括起来,创建子模式,该子模式会被保存,方便之后的引用和处理,同样的,() 也需要使用\转义,否则会被当成普通字符处理。
捕获分组
| Bash |
|---|
| root@debian:~# echo "abcabcabcabc" | grep '\(abc\)\+'
abcabcabcabc
root@debian:~#
|
分组引用
| Bash |
|---|
| root@debian:~# echo "180-1234-1234" | sed 's/\([[:digit:]]\{3\}\)-\([[:digit:]]\{4\}\)-\([[:digit:]]\{4\}\)/+86 \1 \2 \3/'
+86 180 1234 1234
root@debian:~#
|
grep 主要是用以匹配和查找,所以它不具备捕获分组和引用分组的功能,所以这里使用sed 进行替代,若是太难了,可以看如下案例:
| Bash |
|---|
| root@debian:~# echo "180-1234-1234" | sed 's/180/182/'
182-1234-1234
root@debian:~#
|
如上是一个简单的替换,sed 's/old/new/'。
如果引用了分组
| Bash |
|---|
| root@debian:~# echo "180-1234-1234" | sed 's/\(180\)-\(1234\)-\(1234\)/\1 \2 \3/'
180 1234 1234
root@debian:~#
|
这里将180捕获为分组1、1234捕获为分组2、最后的1234捕获为分组3,在进行替换的时候,可以直接使用\1、\2等直接引用分组内容。分组最多为1到9共9个。
总结
基本正则表达相对而言,比较简单,需要注意的是,在基本正则表达式中,大括号{} 和小括号()都必须要使用\ 进行转义,否则将表示字符本身。而. 、*、^、$ 等,默认就是正则,如果需要使用其字符本身,则需要使用\进行转义。
哦,对了,在shell中,我们查询文件,可能会用到类似的写法:
| Bash |
|---|
| root@debian:~# ls -d ns[123]
ns1 ns2
root@debian:~# ls -d *
BRE Desktop Documents Downloads hello Music ns1 ns2 Pictures Public Templates Videos
root@debian:~# ls -d .*
.bash_history .cache .dmrc .local .ssh .viminfo .Xauthority .xsession-errors.old
.bashrc .config .lesshst .profile .vboxclient-vmsvga-session-tty7.pid .wget-hsts .xsession-errors
root@debian:~#
|
这个其实是bash中的通配符匹配,不是正则表达式哦,不要弄混了。