Crane
Table_bottom

Search
Loading
Table_bottom

分类
Table_bottom

随机文章
Table_bottom

标签云
Table_bottom

最新评论
Table_bottom

链接
Table_bottom

功能
Table_bottom

正则表达式之一

Crane posted @ 2009年3月07日 13:31 in Linux with tags 正则表达式 RegEx , 4900 阅读

我想从Linux开始说起,他继承了Unix的设计思想,Keep it simple,由一个内核和许许多多小工具组成,内核负责管理资源,工具负责完成作业,彼此配合,实现人们需要的功能,提供人们所需要的服务。由simple的原则,每一个工具只专注少量的工作,他们通过配合,是的,他们可以配合的很好(这是和windows完全不同的地方),所以每个工具只需要解决好自己真正要干的活,别的事不用担心,会有工具负责的,相当于包产到户,产量绝对有保证。

也正是由于simple原则,linux里面的所有配置文件都是纯文本格式,这样只需要一个文本编辑器就可以搞定所有的配置,这样的话系统管理员在命令行界面下就可以干完他大半的工作,但是面对一大堆的文本,要找出自己想要的东西也不是一件容易的事,要是你知道确切的要找的内容,那么一个简单的search就办到了,但是若是你要找一类相似的东西,比如E-mail地址,URL等,它就无能为力了,这下就是正则表达式出马的时候了,它有强大的匹配功能,通过描述字符串的特征,可以轻易帮你找到你想要的东西,所以现在几乎所有的只要是处理字符串的工具(文本编辑器、文字处理软件、系统工具、数据库引擎等),编程语言(Java、JScript、Visual Basic、VBScript、JavaScript、ECMAScript、C、C++、C#、elisp、Perl、Python、Tcl、Ruby、PHP、sed和awk等),都支持正则表达式,也正是有了正则表达式,程序员可以提高效率,使得生产力又得到了极大的提高。

其实从低层面来说,正则表达式描述的是一串文本(a chunk of text)的特征。读者可以用它来验证用户输入的数据,或者也可以用它来检索大量的文本。从较高的层面上来说,正则表达式容许用户掌控他们自己的数据—— 控制这些数据,让他们为自己服务。掌握正则表达式,就是掌握自己的数据。

你也许使用VIM写程序,想搞清楚它那语法高亮是怎么实现的;也许看到过类似[a-zA-Z_][a-zA-Z0-9_]*之类的东西,不知道前面这串看似很乱的东西是什么;也许你的程序要处理一些数据,你想要得到其中的E-mail地址,但不知道程序应该怎么走;其实这些全是正则表达式的能力范围。

就说上面写到的那个简单的正则表达式的例子吧!那个表示的是匹配变量名,我们都知道变量要以字母或下划线开始,然后其余可以是字母,数字或下划线。为了看懂上面那个例子,有必要了解一下正则表达式的一些基本常识。

在正则表达式中,怎么描述一串文本的特征呢,它有一套规定,规定一些字符代表特定的意义,就是术语中所说的元字符,用元字符和普通字符配合起来描述字符串,下面就是一些基本的元字符。

^        匹配一行的开始(单独使用)

[^?]        匹配除了?(?表示的是不希望匹配的一个列表)以外的任何一个字符(在[ ]内使用)

$        匹配一行的结尾

[avdee]        匹配中括号的任意一个字符,[ ]里面也可以用一个”-“表示范围,像下面一样。

[a-z]        匹配一个小写字母

[A-Z]        匹配一个大写字母

[0-9]        匹配一个数字

.        匹配任意字符

|        匹配这个字符左边或右边的部分,通常写成“(word1|word2)"的形式,同时这个括号里的东西算一个整体,他们是一个部分。

+        匹配这个字符前面的部分至少一次,这个部分要不是一个字符,要不就是上文所说的部分,不一定是上文那种形式,只要是在括号中就行,下同。

*        匹配这个字符前面的部分任意次,可以为零次

?        匹配这个字符前面的部分零或一次

\<   \>        分别匹配一个单词的开始和结尾,这样就可以用这两个的组合来匹配一个单词

\元字符        匹配元字符,要不然它们会被按照它们所代表的意义处理

先来热一下身,比如^cat, ^ 表示一行开始,然后紧接着是一个单词 cat ,所以它表示的是以cat开头的行,类似的 cat$ 表示以cat结束的行,而 ^cat$ 则表示只有 cat 一个单词的行,再比如你不知道奶酪应该怎么拼,是cheese呢还是chease,可以这样写che[ea]se,中间的[ea]表示这里可以是e或者a,也许你觉得这样看着不明显,没关系,可以写成这样(cheese|chease),用到了”|"这个元字符,表示匹配左边或右边的部分。或者你不知道cheese中间是一个e呢还是两个,可以这样写che+se,注意这里是+号,表示至少应该有一个,若是*的话,表示可以一个e都没有,或者有好多个,而是?的话则表示是有e呢还是没有。

下面来看上面那个例子,[a-zA-Z_][a-zA-Z0-9_]*

可以看到这个可以分成三个部分,前面两个中括号中的各是一个部分,后面那个星号是一个部分。参考上面的规定,可以知道第一个部分表示的是第一个字符是个字母或下划线,后面的就是任意字母或数字或下划线,那个*表示长度不限,这正是变量取名的规则,所以它匹配的是变量名。

 再来一个例子,比如说要匹配一个时间,像这样的:"9:17 am" or "12:30 pm",如果说写成这样:[0-9]?[0-9]:[0-9][0-9] (am|pm),是可以匹配出我们想要的时间,但也会有我们不需要的,像99:99 am之类的错误也会带进来,因此我们要注意每一位的范围,然后就可以写出像这样的:(1[012]|[1-9]):[0-5][0-9] (am|pm),就可以符合要求了。如果要匹配24小时制的话,同样考虑范围问题,可以把前面的换成[01]?[0-9]|2[0-3]就可以匹配24小时制了。

其实这只是用正则表达式来牛刀杀鸡,它的强大功能还多着呢!


登录 *


loading captcha image...
(输入验证码)
or Ctrl+Enter