【Linux Shell脚本编程】通配符与正则表达式的区别与介绍

TangLu 未命名 2018-06-26 7823 0

什么时候使用通配符?什么时候使用正则表达式?

1、不需要思考的判断方法:grep(egrep)、awk、sed三剑客中使用的都是正则表达式

2、对文件或目录名匹配-->通配符

3、对文本内容上进行匹配-->正则表达式


一、通配符常用语法:
1、*:匹配任意长度的任意字符,就是说“什么都可以”。

/etc/fs*  #/etc中以fs开头的文件将被匹配
/tmp/my*1  #/tmp中以my开头并且以1结尾的文件将被匹配


2、?与任何单个字符匹配。

myfile?  #文件名为myfile且后面跟任一单个字符的任何文件将被匹配
/tmp/notes?txt  #如果/tmp/notes.txt和/tmp/notes_txt都存在的话他们都会被匹配

3、[ ]:与?相似,可以匹配一个括号内的字符,也可以用“-”进行范围指定。

myfile[12]  #将与myfile1和myfile2匹配
[Cc]hange[Ll]og  #Changelog、ChangeLog、changeLog以及changelog都可匹配,与大写形式的变形匹配时,使用括弧通配符很有用
ls /etc/[0-9]  #将列出 /etc 中以数字开头的所有文件。
ls /tmp/[A-Za-z]  #将列出/tmp中以大写字母或小写字母开头的所有文件。



4、[!]:括号内的“!”代表非的意思,即不与括弧中的字符匹配。

rm myfile[!9]  #删除除了myfile9之外的名为myfile加一个字符的所有文件


使用通配符注意事项 
由于 bash会将一些字符(?,*,等)进行特殊处理,因此输入这些字符到命令中时,把字符加上单引号
是最好的选择。


二、正则表达式:

1、基础正则表达式(默认不认识扩展正则里的元字符,除非使用转义符)

.  #匹配任意一个字符,和通配符中的?作用一样
*  #匹配*号前面的字符出现0次或任意次
^  #匹配行首,如grep "^hello" test.txt,代表匹配hello开头的行
$  #匹配行尾,如hello$,代表hello结束的行
[ ]  #匹配指定范围内的任意单个字符,如[a-z]代表从26个小写字母里任选其一 
[^]  #匹配的结果取反,如[^0-9],代表匹配的内容非数字
\{ m,n\}  #m匹配出现的次数,n代表最大次数,"\"是转义符。如果想表示至少多少次(上不封顶)可以用\{m,\},如至少5次{5,\}。至多的话需要表示为\{0,n\},精确多少次表示方法为{m\}
\<  #锚定词首,如\<root代表单词首部是root的才符合规则    
\>  #锚定词尾



2、扩展正则表达式(在基础正则上添加了更多元字符,无需转义

()  #分组,(who|what),表示匹配who或者what,也可以做后项引用,如^(.*)$ /msie/$1,这里的$1取的是括号内的内容,在Nginx Rewrite中比较常用
?  #匹配前面的字符0次或1次,可以理解为“?”前的一个字符要么有,要么没有
+  #重复前一个字符一次或多次
|  #或



3、POSIX字符类

[[:alnum:]]:字母与数字字符
[[:alpha:]]:字母字符,包含大小写
[[:blank:]]:空格与制表符
[[:digit:]]:数字
[[:lower:]]:小写字母
[[:upper:]]:大写字母
[[:space:]]:包括换行符、回车等在内的所有空白字符
[[:punct:]]:标点符号


4、其他元字符

# \d  匹配阿拉伯数字,等同于[0-9]。
rewrite ^/course-(\d+).html$ /course/$1/course.html break  #访问/course-11.html页面会跳转到/course/11/course.html这样的页面
# \D  匹配阿拉伯数字之外的任意字符,等同于[^0-9]。
# \x  匹配十六进制数字,等同于[0-9A-Fa-f]。
# \X  匹配十六进制数字,等同于[^0-9A-Fa-f]。
# \w  匹配单词字母,等同于[0-9A-Za-z_]。
# \W  匹配单词字母之外的任意字符,等同于[^0-9A-Za-z_]。
# \t  匹配<TAB>字符。
# \s  匹配空白字符,等同于[ \t]。
# \S  匹配非空白字符,等同于[^\t]。
# \a  所有的字母字符. 等同于[a-zA-Z]
# \l  小写字母 [a-z]
# \L  非小写字母 [^a-z]
# \u  大写字母 [A-Z]
# \U  非大写字母 [^A-Z]


替换变量(后项引用) 
在正规表达式中使用 \( 和 \) 符号括起正规表达式,即可在后面使用1、2等变量来访问 \( 和 \) 中的内容

%s/\(192.168.100\).10)/\1.20/    #把192.168.100.10替换为192.168.100.20
%s#\(192.168.100.\)10)#\120#    #注意写法区别
%s#\(192.\)\(168.\)\(100.\)10#\1\2\320#
3,10s/\(.*\)/#\1/    #给3-10行增加注释


三、正则表达式元字符语法示例

[  ] :与通配符中的[  ]作用相同。

$ grep dev.hda[12] /etc/fstab
/dev/hda1       /boot           reiserfs        noauto,noatime,notail 1 2
/dev/hda2       swap            swap            sw 0 0


[^]:代表使方括号中的意思相反。在正则表达式中使用 [^],而在glob中使用 [!]:

$ grep dev.hda[^12] /etc/fstab
/dev/hda3       /               reiserfs        noatime,ro 1 1
#/dev/hda4      /mnt/extra      reiserfs        noatime,rw 1 1


*: *号前面的一个字符出现零次或者多次:

ab*c(与 abbbbc 匹配但不与 abqc 匹配,*号前面字符出现多次的情况)
ab*c(与 abc 匹配但不与 abbqbbc 匹配,*号前面字符出现一次的情况)
ab*c(与 ac 匹配但不与 cba 匹配,*号前面字符出现零次的情况)
.*(与任何字符串匹配)
foo.*(与以 foo 开始的任何字符串相匹配)


^和$:每行的开始或结尾:

grep ^# /etc/fstab  #匹配以#开始的行
grep ^$ /etc/fstab  #匹配空白行



四、正则表达式常用示例

1、校验数字的表达式

#数字
^[0-9]*$
#n位的数字
^\d{n}$
#至少n位的数字
^\d{n,}$


2、校验字符的表达式

#汉字
^[\u4e00-\u9fa5]{0,}$
#英文和数字
^[A-Za-z0-9]+$ 或 ^[A-Za-z0-9]{4,40}$
#长度为3-20的所有字符
^.{3,20}$
#由26个英文字母组成的字符串
^[A-Za-z]+$
#由26个大写英文字母组成的字符串
^[A-Z]+$
#由26个小写英文字母组成的字符串
^[a-z]+$


3、特殊需求表达式

#Email 地址
^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$
#域名
[a-zA-Z0-9][-a-zA-Z0-9]{0,62}(/.[a-zA-Z0-9][-a-zA-Z0-9]{0,62})+/.?
#URL
[a-zA-z]+://[^\s]* 或 ^http://([\w-]+\.)+[\w-]+(/[\w-./?%&=]*)?$
#手机号码
^(13[0-9]|14[5|7]|15[0|1|2|3|5|6|7|8|9]|18[0|1|2|3|5|6|7|8|9])\d{8}$
#电话号码(“XXX-XXXXXXX”、”XXXX-XXXXXXXX”、”XXX-XXXXXXX”、”XXX-XXXXXXXX”、”XXXXXXX”和”XXXXXXXX)
^(\(\d{3,4}-)|\d{3.4}-)?\d{7,8}$
#国内电话号码(0511-4405222、021-87888822)
\d{3}-\d{8}|\d{4}-\d{7}
#身份证号(15位、18位数字)
^\d{15}|\d{18}$
#短身份证号码(数字、字母x结尾)
^([0-9]){7,18}(x|X)?$ 或 ^\d{8,18}|[0-9x]{8,18}|[0-9X]{8,18}?$


评论