一、定义
正则表达式是你所定义的模式模板(pattern template
),Linux
工具可以用它来过滤文本。Linux
工具(比如 sed
编辑器或 gawk
程序)能够在处理数据时使用正则表达式对数据进行模式匹配。如果数据匹配模式,它就会被接受并进一步处理;如果数据不匹配模式,它就会被滤掉。
正则表达式模式利用通配符来描述数据流中的一个或多个字符。Linux
中有很多场景都可以使用通配符来描述不确定的数据。
二、正则表达式的类型
使用正则表达式最大的问题在于有不止一种类型的正则表达式。Linux
中的不同应用程序可能会用不同类型的正则表达式。
正则表达式是通过正则表达式引擎(regular expression engine
)实现的。正则表达式引擎是 一套底层软件,负责解释正则表达式模式并使用这些模式进行文本匹配。
在 Linux
中,有两种流行的正则表达式引擎:
POSIX
基础正则表达式(basic regular expression
,BRE
)引擎POSIX
扩展正则表达式(extended regular expression
,ERE
)引擎
三、特殊字符
元字符 | 作用 |
---|---|
^ | 匹配行首. 例如:^hello 会匹配以 hello 开头的行. |
$ | 匹配行尾. 例如:hello& 会匹配以 hello 结尾的行. |
[] | 匹配中括号中指定的任意一个字符,制匹配一个字符. 例如:[aoeiu] 匹配任意一个元音字母,[0-9] 匹配任意一位数字,[a-z][0-9] 匹配小写字和一位数字构成的两位字符. |
[^] | 匹配除中括号的字符以外的任意一个字符. 例如:[^0-9] 匹配任意一位非数字字符,[^a-z] 表示任意一位非小写字母. |
[[:alpha:]] | 匹配任意字母字符,不管是大写还是小写. |
[[:alnum:]] | 匹配任意字母数字字符 0~9 、A~Z 或 a~z . |
[[:blank:]] | 匹配空格或制表符. |
[[:digit:]] | 匹配 0~9 之间的数字. |
[[:lower:]] | 匹配小写字母字符 a~z . |
[[:print:]] | 匹配任意可打印字符. |
[[:punct:]] | 匹配标点符号. |
[[:space:]] | 匹配任意空白字符:空格、制表符、NL 、FF 、VT 和 CR . |
[[:upper:]] | 匹配任意大写字母字符 A~Z . |
* | 前一个字符匹配 0 次或任意多次. |
? | 前面的字符可以出现 0 次或 1 次. |
+ | 前面的字符可以出现 1 次或多次,但必须至少出现1次. |
\ | 转义符. 用于取消特殊符号的含义. |
{n} | 表示其前面的字符恰好出现 n 次. 例如:[0-9]\{4\} 匹配 4 位数字,[1][3-8][0-9]{9} 匹配手机号码. |
{n,} | 表示其前面的字符出现不小于 n 次. 例如:[0-9]{2,} 表示两位及以上的数字. |
{n,m} | 表示其前面的字符至少出现 n 次,最多出现 m 次. 例如:[a-z]{6,8} 匹配 6 到 8 位的小写字母. |
| | 管道符号允许你在检查数据流时,用逻辑 OR 方式指定正则表达式引擎要用的两个或多个模式. |
( ) | 用圆括号进行分组,该组会被视为一 个标准字符. |
四、正则表达式实战
1、目录文件计数
1、确定要处理的文本格式,我们对 PATH
环境变量中定义的目录里的可执行文件进行计数。
onlylove@ubuntu:~$ echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin
onlylove@ubuntu:~$
2、分析要处理文本
关键:PATH
中的每个路径由冒号分隔。
处理:使用 sed
编辑器将冒号用空格替换。
实现:处理过后,用 for
进行分离。
3、实现
#!/bin/bash
mypath=$(echo $PATH | sed 's/:/ /g')
for directory in $mypath
do
echo $directory
done
4、测试
onlylove@ubuntu:~/my/shell/01$ echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin
onlylove@ubuntu:~/my/shell/01$
onlylove@ubuntu:~/my/shell/01$ ls
test.sh
onlylove@ubuntu:~/my/shell/01$ ./test.sh
/usr/local/sbin
/usr/local/bin
/usr/sbin
/usr/bin
/sbin
/bin
/usr/games
/usr/local/games
/snap/bin
onlylove@ubuntu:~/my/shell/01$
2、解析邮件地址
1、确定要处理的文本,邮件地址的基本格式为:
username@hostname
2、分析数据
username
值可用字母数字字符以及以下特殊字符:
- 点号
- 单破折线
- 加号
- 下划线
邮件地址的 hostname
部分由 一个或多个域名和一个服务器名组成。服务器名和域名也必须遵照严格的命名规则,只允许字母数字字符以及以下特殊字符:
- 点号
- 下划线
3、设计
username
中可以有多个有效字符。使用以下语句:
^([a-zA-Z0-9_\-\.\+]+)@
- 分组指定了用户名中允许的字符。
- 加号表明必须有至少一个字符。
hostname
使用同样的方法来匹配服务器名和子域名。使用以下语句:
([a-zA-Z0-9_\-\.]+)
对于顶级域名,有一些特殊的规则。顶级域名只能是字母字符,必须不少于二个字符(国家或地区代码中使用),并且长度上不得超过五个字符。下面就是顶级域名用的正则表达式模式:
\.([a-zA-Z]{2,5})$
将整个模式放在一起会生成如下模式:
^([a-zA-Z0-9_\-\.\+]+)@([a-zA-Z0-9_\-\.]+)\.([a-zA-Z]{2,5})$
4、实现
#!/bin/bash
str=`echo $1 | gawk '/^([a-zA-Z0-9_\-\.\+]+)@([a-zA-Z0-9_\-\.]+)\.([a-zA-Z]{2,5})$/{print $0}'`
if [ ! -n "${str}" ]
then
echo "validation is wrong."
else
echo "Your eamil is: ${str}"
fi
5、测试
onlylove@ubuntu:~/my/shell/01$ ls
test.sh
onlylove@ubuntu:~/my/shell/01$ ./test.sh
validation is wrong.
onlylove@ubuntu:~/my/shell/01$
onlylove@ubuntu:~/my/shell/01$ ./test.sh mail@test.com
Your eamil is: mail@test.com
onlylove@ubuntu:~/my/shell/01$