迷人的正则表达式
正则表达式,又称正规表示式、正规表示法、正规表达式、规则表达式、常规表示法(英语:Regular Expression,在代码中常简写为regex、regexp或RE),计算机科学的一个概念。正则表达式使用单个字符串来描述、匹配一系列符合某个句法规则的字符串。在很多文本编辑器里,正则表达式通常被用来检索、替换那些符合某个模式的文本。——维基百科
专注于为中小企业提供网站制作、成都网站设计服务,电脑端+手机端+微信端的三站合一,更高效的管理,为中小企业安定免费做网站提供优质的服务。我们立足成都,凝聚了一批互联网行业人才,有力地推动了千余家企业的稳健成长,帮助中小企业通过网站建设实现规模扩充和转变。
正则表达式是计算机智能的一种体现,她能让我们在繁杂的计算机文本之中找到我们最想要的东西,在她那规则而又朦胧的面纱之下是一张优雅而又调皮的面孔,对于初入Linux大门的男人来说,无不拜倒在她的石榴裙下,而本文所要做的就是如何俘获她的芳心。
一、了解她的身世
在1956 年,美国的一位名叫Stephen Kleene的数学科学家,他在Warren McCulloch和Walter Pitts早期工作的基础之上,发表了一篇题目是《神经网事件的表示法》的论文,利用称之为正则集合的数学符号来描述此模型,引入了正则表达式的概念。正则表达式被作为用来描述其称之为“正则集的代数”的一种表达式,因而采用了“正则表达式”这个术语。之后一段时间,人们发现可以将这一工作成果应用于其他方面。Ken Thompson就把这一成果应用于计算搜索算法的一些早期研究,Ken Thompson是 Unix的主要发明人,也就是大名鼎鼎的Unix之父。Unix之父将此符号系统引入编辑器QED,然后是Unix上的编辑器ed,并最终引入grep。近二十年来,在WINDOW的阵营下,正则表达式的思想和应用在大部分 Windows 开发者工具包中得到支持和嵌入应用!目前主流的开发语言(PHP、C#、Java、C++、VB、Javascript、Ruby以及python等)、数以亿万计的各种应用软件中,都可以看到正则表达式优美的舞姿。
二、揭开她的面纱
好了,继上次inode之后我们又遇到了一个让人无从下手的东西,但是不管怎么说我们还得学她,所以先来看看正则表达式都有些什么吧:
基本正则表达式元字符:
字符匹配:
. :匹配任意单个字符
[]: 匹配指定范围内的任意单个字符
[^]: 匹配指定范围外的任意单个字符
[0-9], [[:digit:]], [^0-9], [^[:digit:]]
[a-z], [[:lower:]]
[A-Z], [[:upper:]]
[[:space:]]
[[:punct:]]
[0-9a-zA-Z], [[:alnum:]]
[a-zA-Z], [[:alpha:]]
次数匹配:在期望匹配字符后面提供一个控制符,用于表达匹配其前面字符指定的次数
* : 任意长度,表示0次、1次或多次;
.*: 任意长度的任意字符
工作于贪婪模式
\?:0次或1次;表示其左侧字符可有可无
\+: 1次或多次;表示其左侧字符至少出现1次;
\{m\}:m次;表示其左侧字符精确出现m次;
\{m,n\}:至少m次,至多n次;
\{0,n\}:至多n次;
\{m,\}:至少m次;
位置锚定:
^: 锚定行首
$: 锚定行尾
^$: 匹配空白行;
单词锚定:由非特殊字符组成的连续的字符串
\< :锚定词首,也可用\b
\> :锚定词尾,也可以用\b
\
分组:\(\)
\1,\2...\n:用于表示引用前面分组的内容
扩展的正则表达式:
字符匹配:
.
[]
[^]
次数匹配:
*: 任意次
?:0或1次
+: 至少1次
{m}:精确匹配m次;
{m,n}:至少m次,至多次;
{m,}:至少m次;
{0,n}:至多次;
位置锚定:
^
$
\<, \b
\>, \b
分组:
()
引用:\1, \2, ...
或者:
a|b:a或者b
或者两侧的所有内容;
三、强吻她
额,我知道走到这一步可能有点出乎大家的意料,不过要知道强吻一个女孩儿是最快得到答复的一种方式,不是吗?OK,想要强吻我们就需要手、嘴并用,好了来看看我们能用的手和嘴都有哪些吧。我们在了解女神身世的时候知道我们的Unix之父引入了grep,在Unix的grep家族中包括grep、egrep和fgrep。egrep和fgrep的命令只跟grep有很小不同。egrep是grep的扩展,支持更多的元字符,fgrep就是把所有的字母都看作单词,也就是说,正则表达式中的元字符表示回其自身的字面意义,不再特殊。
好了,我们的手嘴已经就绪开始行动吧:
我们循序渐进先来个简单动作-->查找/proc/meminfo中以s|S开头的行
我们一只手的用法grep [OPTIONS] PATTERN [FILE...],其中^为锚定行首,[sS]表示只能选择这个集合之中s和S两个字母。
我们再来一个-->找出/etc/passwd文件中的一位或者两位数,为了让我们的动作不那么苍白,我们给她点颜色看看
--color选项表示以彩色形式显示搜索出来的内容,\<\>这两个组合起来可以确定一个单词,[0-9]表示一个数字范围在0-9之中选,而\?表示其前面的字符可出现一次或者不出现。
我们的动作越来越熟练了-->我们给出几个句子,看看如何使用分组
我们输出了四个句子,其中有两个前后很像,我们用分组和引用把它们找出来了:\(l..e\).*\1,l..e表示以l开头中间根两个任意字母,然后把这个看成一个整体,.*表示任意长度的字符,\1表示引用前面使用\(\)括起来的内容。
如果要一直使用带颜色输出我们可以通过定义别名的形式为以后少点麻烦:
[root@bogon ~]# alias grep='grep --color'
接下来我们来点有难度的-->取出一个路径的路径名
grep -o表示只显示被选中内容,这里我们用到了两次grep,第一次[^/]表示最后匹配到不以/结尾的字符,/.*/就表示两个分割符之间的内容了,如果我们想要得到类似dirname命令那样的格式可以使用
[root@bogon ~]# echo '/etc/rc.d/init.d/' | grep -o '/.*[^/]' | grep -o '/.*/' | grep -o '/.*[^/]' 大家可以去试一下。
我们不能一直使用一只手,该清楚另一只了-->取出一个路径的基名
egrep等于grep -E,都代表是扩展的正则表达式,+表示其前面的[^/]出现一次或者多次,?我们前面解释过了,$表示锚定行尾,在结尾处带有/的路径名,我们可以使用cut切一下就可以了。
我们再来巩固一下成果:
第一个我们的目的是在字符串中找到前后名称一致而后缀不一致的内容;第二个我们的目的是在字符串中找到符合邮箱格式的内容,大家自己体会一下吧,我就不再解释了。为了防止成为“三只手”,我就不再介绍fgrep了,它其实很简单,就是字符本来样子的匹配。经过这三个强劲的“泡妞”步骤我想你应该可以俘获她的芳心了,但是如果想把这位狡猾的女神娶回家还需要各位更加深入的努力啊,知己知彼方能百战不殆嘛!
好了希望这篇文章能够给您带来帮助,敬请各位看官提出此文章的不当之处,拜谢!
PS:grep,egrep,fgrep的使用方法各位使用man命令看一下吧,本文不再赘述。
[root@bogon ~]# echo -e 'adsfqw@163.com\nqwqe@qq;com\nFreedom@gmail.com.com\nadfa.msn.com' | egrep --color '[[:alnum:]]+@[[:alnum:]]+\.[[:alpha:]]+$' --> 修正提取邮箱的BUG
标题名称:迷人的正则表达式
浏览路径:http://myzitong.com/article/gjseso.html