枫林在线论坛精华区>>程序设计
[34852] 主题: 揭开正则表达式语法的神秘面纱
作者: leaflet (Leaf闭关中…)
标题: 揭开正则表达式语法的神秘面纱[转载]
来自: 202.109.*.*
发贴时间: 2003年01月02日 16:23:22
长度: 5310字
揭开正则表达式语法的神秘面纱

正则表达式(REs)通常被错误地认为是只有少数人理解的一种神秘语言。在
表面上它们确实看起来杂乱无章,如果你不知道它的语法,那么它的代码
在你眼里只是一堆文字垃圾而已。实际上,正则表达式是非常简单并且可
以被理解。读完这篇文章后,你将会通晓正则表达式的通用语法。 

支持多种平台
正则表达式最早是由数学家Stephen Kleene于1956年提出,他是在对自然
语言的递增研究成果的基础上提出来的。具有完整语法的正则表达式使用
在字符的格式匹配方面上,后来被应用到熔融信息技术领域。自从那时起
,正则表达式经过几个时期的发展,现在的标准已经被ISO(国际标准组织
)批准和被Open Group组织认定。

正则表达式并非一门专用语言,但它可用于在一个文件或字符里查找和替
代文本的一种标准。它具有两种标准:基本的正则表达式(BRE),扩展的正
则表达式(ERE)。ERE包括BRE功能和另外其它的概念。

许多程序中都使用了正则表达式,包括xsh,egrep,sed,vi以及在UNIX平台
下的程序。它们可以被很多语言采纳,如HTML 和XML,这些采纳通常只是
整个标准的一个子集。

比你想象的还要普通
随着正则表达式移植到交叉平台的程序语言的发展,这的功能也日益完整
,使用也逐渐广泛。网络上的搜索引擎使用它,e-mail程序也使用它,即
使你不是一个UNIX程序员,你也可以使用规则语言来简化你的程序而缩短
你的开发时间。

正则表达式101
很多正则表达式的语法看起来很相似,这是因为你以前你没有研究过它们
。通配符是RE的一个结构类型,即重复操作。让我们先看一看ERE标准的最
通用的基本语法类型。为了能够提供具有特定用途的范例,我将使用几个
不同的程序。

字符匹配
 

正则表达式的关键之处在于确定你要搜索匹配的东西,如果没有这一概念
,Res将毫无用处。

每一个表达式都包含需要查找的指令,如表A所示。

Table A: Character-matching regular expressions
 
操作
 解释
 例子
 结果
 
.
 Match any one character
 grep .ord sample.txt
 Will match “ford”, “lord”, “2ord”, etc. in the file sampl
e.txt.
 

 Match any one character listed between the brackets
 grep ord sample.txt
 Will match only “cord”, “nord”, and “gord”
 

 Match any one character not listed between the brackets
 grep ord sample.txt
 Will match “lord”, “2ord”, etc. but not “cord” or “nord”

 
 
  
 grep ord sample.txt
 Will match “aord”, “bord”, “Aord”, “Bord”, etc.
 
 
  
 grep ord sample.txt
 Will match “Aord”, “aord”, etc. but not “2ord”, etc.
 


重复操作符
重复操作符,或数量词,都描述了查找一个特定字符的次数。它们常被用
于字符匹配语法以查找多行的字符,可参见表B。

Table B: Regular expression repetition operators
 
操作
 解释
 例子
 结果
 
?
 Match any character one time, if it exists
 egrep “?erd” sample.txt
 Will match “berd”, “herd”, etc. and “erd”
 
*
 Match declared element multiple times, if it exists
 egrep “n.*rd” sample.txt
 Will match “nerd”, “nrd”, “neard”, etc.
 
+
 Match declared element one or more times
 egrep “+erd” sample.txt
 Will match “nerd”, “nnerd”, etc., but not “erd”
 
{n}
 Match declared element exactly n times
 egrep “{2}erd” sample.txt
 Will match “cherd”, “blerd”, etc. but not “nerd”, “erd”
, “buzzerd”, etc.
 
{n,}
 Match declared element at least n times
 egrep “.{2,}erd” sample.txt
 Will match “cherd” and “buzzerd”, but not “nerd”
 
{n,N}
 Match declared element at least n times, but not more than N ti
mes
 egrep “n{1,2}rd” sample.txt
 Will match “nerd” and “neerd”
 


锚是指它所要匹配的格式,如图C所示。使用它能方便你查找通用字符的合
并。例如,我用vi行编辑器命令:s来代表substitute,这一命令的基本语
法是:

s/pattern_to_match/pattern_to_substitute/
 

Table C: Regular expression anchors
 
操作
 解释
 例子
 结果
 
^
 Match at the beginning of a line
 s/^/blah /
 Inserts “blah “ at the beginning of the line
 
$
 Match at the end of a line
 s/$/ blah/
 Inserts “ blah” at the end of the line
 
\<
 Match at the beginning of a word
 s/\</blah/
 Inserts “blah” at the beginning of the word
 
 
  
 egrep “\<blah” sample.txt
 Matches “blahfield”, etc.
 
\>
 Match at the end of a word
 s/\>/blah/
 Inserts “blah” at the end of the word
 
 
  
 egrep “\>blah” sample.txt
 Matches “soupblah”, etc.
 
\b
 Match at the beginning or end of a word
 egrep “\bblah” sample.txt
 Matches “blahcake” and “countblah”
 
\B
 Match in the middle of a word
 egrep “\Bblah” sample.txt
 Matches “sublahper”, etc.
 

 

间隔
Res中的另一可便之处是间隔(或插入)符号。实际上,这一符号相当于一个
OR语句并代表|符号。下面的语句返回文件sample.txt中的“nerd” 和 “
merd”的句柄:

egrep “(n|m)erd” sample.txt

间隔功能非常强大,特别是当你寻找文件不同拼写的时候,但你可以在下
面的例子得到相同的结果:

egrep “erd” sample.txt

当你使用间隔功能与Res的高级特性连接在一起时,它的真正用处更能体现
出来。

一些保留字符
Res的最后一个最重要特性是保留字符(也称特定字符)。例如,如果你想要
查找“ne*rd”和“ni*rd”的字符,格式匹配语句“n*rd”与“neeeeerd
” 和 “nieieierd”相符合,但并不是你要查找的字符。因为‘*’(星号
)是个保留字符,你必须用一个反斜线符号来替代它,即:“n\*rd”。其
它的保留字符包括:

^ (carat) 
. (period) 
+(\.+)*@+(\.+)*$",$sendto)

你可以看到,程序的意图很难把握。但如果你抛开保留字符,你常常会错
误地理解代码的意思。

总结
在本文中,我们揭开了正则表达式的神秘面纱,并列出了ERE标准的通用语
法。如果你想阅览Open Group组织的规则的完整描述,你可以参见:Regu
lar Expressions,欢迎你在其中的讨论区发表你的问题或观点。

 

========== * * * * * ==========
返回