POSIX正则表达式的一些事
雪天蛤蟆跳跳 360云计算
女主宣言
编程中经常会遇到这些特殊字符: *?+[]{}^$()|,他们有什么特殊的含义?通配符、BRE、ERE、PCRE是什么鬼,本篇文章介绍了前三种。 PS:丰富的一线技术、多元化的表现形式,尽在“HULK一线技术杂谈”,点关注哦!
下面有3个问题,如果你能回答出来,那么本篇文章可能对你来说就是小菜一碟,浪费了您的宝贵时光,只能在这里说一声抱歉。如果你有一些不太了解,看完这篇文章你应该就对这些有所了解,可以再试着回来看看这三个问题。
- 通配符是什么,[A-Z]在不同的语言环境表示的字符都一样吗?
- 什么情况下用的是通配符,什么情况下用的是正则表达式?
- POSIX正则表达式分为哪两种?他们的区别是什么?
介绍
因为shell频繁的使用文件名,所以shell体用了特殊字符来帮助快速的指定一组文件名——通配符。
* 匹配任意多个字符
? 匹配任意一个字符
[characters] 匹配任意一个字符
[!characters] 匹配任意不是字符集中的字符
[[:class:]] 任意属于指定字符类中的字符
先介绍前四个的: (所有文件),g(g开头的文件),b*.txt(b开头的txt文件),Data???(开头是Data长度为7的文件),[abc](以a或者b或者c开头的文件),abc[0-9][0-9](以abc开头后跟两个数字的文件),[A-Z](这个在不同的语言设置的系统下显示不同的结果)
我们看几个例子: 下面的例子是在 centos下的。
A-Z的差异
我们看到上面的最后一个确实没有输出我们想要的结果,这是为什么?
且听我们慢慢道来,话说UNIX刚刚出道的时候,只是在美国,所以那个时候的ASCII,一共有0-127个,他们的字母排序是ABC...XYXabc...xyz,但是随着UNIX的慢慢的发展开始在非英文为母语的国家扩散了,于是就扩展了ASCII字符,使用了整个8位添加了字符128-255,这样容纳了更多的语言。
为了支持这种能力,POSIX标准介绍了一种叫做locale的概念,它可以调整为自己国家的语言习惯,有的国家是按照子典排序来的,他们的排序是aAbBcC...xXyYzZ。
这样在使用ls [A-Z]*的时候其实是匹配了除了a以外的所有的字母。
我们通过一个例子来看一下,实际修改一下locale看看结果:
我们看到上面切换语言之前先改成了LANG="POSIX",然后在切换到其他的,这样我们能看到不同,我试过直接切换不起作用。 什么地方可以使用通配符呢?能加文件名的unix命令都可以用通配符,ls,cat,less,more,vim,grep,sed,awk...
字符类
因为根据不同的locale会有不同的表现,所以POSIX标准搞出来了字符集,把常用的直接指定了
[:alnum:] 匹配任意一字母或者数字 [:alpha:] 匹配任意一个字母 [:digit:] 匹配任意一个数字 [:lower:] 匹配小写字母 [:upper:] 匹配大写字母
我们来测试一下:
发现了这个还是不错的但是表示范围的就有些力不从心了[A-M]这种。
POSIX 正则表达式
我们经常听说,我们的这个程序支持POSIX BRE正则,这个支持POSIX ERE正则,那么我们就来说说POSIX正则表达式。这里只是简单的介绍一下他们的 区别具体的用法每个元字符表示是什么就不细说了。
POSIX基本 VS 扩展正则表达式
POSIX把正则表达式分为了:基本正则表达式(BRE)和扩展正则表达式(ERE)。
那么他们有什么区别呢? 其实他们还是比较相似的就是支持的元字符不同,BRE支持^$.[]*\,ERE除了支持上面的还支持这些(){}?+|。
应用程序的支持 支持BRE的程序有{sed,grep...},支持ERE的程序有{egrep,grep -E,awk...}
练习: 下面的是grep支持的是基础的正则表达式,如果遇到扩展的正则可以用 { 来表示。
下面的是egrep实现同样的命令。
如果需要看他们的区别其实来一个例子就可以看出来了。
对于上的例子可以这么理解:
基础正则表达式 {就是字符串“{” ,{相当于扩展正则表达式里面的{,后面几个的例子我们看到“正常使用是没有问题的”,如果在该加\的地方没有加不该加的地方加了那么会产生不可预料的结果,每个人尝试的结果可能还是不同的,所以记清楚这些内容后,一定要写出来正确的正则表达式,要不过段时间自己都看不懂什么意思了。