正则表达式的学习

   从形式上说,正则表达式是用来刻画符号串集合的一个代数表述。因此,它可以用于描述搜索符号串,也可以用于以形式的方法定义一种语言。正则表达式的搜索要求有一个试图搜索的模式(pattern)和一个被搜索的文本语料库(corpus)。正则表达式的搜索函数将对整个语料库进行搜索,并返回包含该模式的所有文本。

    1 基本正则表达模式

     最简单的正则表达式是由简单字符构成的一个序列。

    正则表达式是区分大小写的;这意味着/woodchuck/与字符串Woodchuck不匹配。我们使用方括号“[”和“]”来解决这个问题。内部有括号的字符串表示所匹配的字符是析取(disjunction)的。例如,与/[wW]/匹配的模式中或者包含w,或者包含W。

可以使用连字符(-)来表示在某个范围内的任何字符。正则表达式/[2-5]/表示字符2,3,4和5范围内的一个任意符号。正则表达式/[b-g]/表示字符b,c,d,e,f和g范围内的一个任意符号。

通过使用脱字符(^),方括号还可以用来表示不出现某个单独的字符。如果在开方括号之后有脱字符,那么相应的模式就是否定的。例如,正则表达式/[^a]/与任何不包含a的单个字符相匹配。但是,这种用法仅当脱字符处于方括号之后的第一个位置时才有效。如果脱字符出现在其他位置,它只能表示脱字符本身。

 

通过使用方括号,解决了woodchuck的大小写问题,但还不能回答前面提出的那个问题:如何既表示woodchuck,又表示woodchucks?我们不能用方括号实现这样的表示,因为方括号允许说“s或S”,但不允许说“s或无”。为此,我们使用/?/来表示“前一个字符或无”,如下例。

 

有一种基于星号或“*”的算符可以允许我们表达“若干个a”,这种算符称为“Kleene*”,意味着“前面紧邻的字符或正则表达式出现零次或连续出现若干次”。

  还有一种重要的字符就是点好(/./),这是一个通配符,表示与任何单个字符(回车符除外)相匹配的字符。

   通配符经常和星号结合起来使用,含义是“任何字符串”;

  锚号(anchor)是把一种正则表达式锚在符号串中的某个特定位置的特殊字符。最普通的锚号就是脱字符(^)和美元符($)。脱字符与行的开始相匹配。正则表达式/^the/表示只单词the出现在一行的开始。这样脱字符就有三种用法:表示一行的开始;在方括号中表示否定;只表示脱字符本身。美元符号$表示一行的结尾。

    此外还有两个其他的锚号:/b表示词届,而/B表示非词届。因此//bthe/b/表示单词the,而不表示单词other。从技术上讲,Perl把词定义为数字、下划线或字母的任何序列这是根据像Perl和C这样的程序中关于词的定义而言的。例如//b99/表示在"There are 99 bottles of"中的符号串99,因为99在一个空白后面。但是,这个正则表达式不表示“There are 299 bottles of”中的符号串99,因为99在一个数字后面。然而这个正则表达式可以表示$99中的99,因为99跟在美元符号$后面,$不是数字、下划线或字母。

   2 析取、组合与优先关系

    假定我们需要搜索关于宠物的文本,而且我们对cat或dog最感兴趣。这时,我们试图搜索符号串cat或dog。因为我们不能使用方括号来搜索cat或dog,所以需要一个称为析取算符的新算符“|”,这样的算符又称作为析取符。正则表达式/cat|dog/表示或者是符号串cat,或者是符号串dog。为了使析取符只能应用特定的模式,我们需要使用圆括号算符"("和")"。把一个模式括在一个个圆括号中,它就能像一个单独的字符来使用,而且在其中可以使用析取符"|"和星号*等算符,因此表达式/gupp(y|ies)/表示析取符仅仅应用于后缀y和ies。

    可见一个算符可能优先于其他算符,因此我们有必要使用括号来表示这种优先关系。在正则表达式中,这种优先关系是通过算符优先层级来形式地描述的。下面的表中给出了正则表达式算符优先的顺序,其优先级从高到低的顺序排列:

   圆括号 ()

  计数符 * + ? {}

  序列与锚   the ^my  end$

  析取符  |

  由于计数符比序列具有更高的有限性,所以/the*/与theeeee相匹配,而不与thethe相匹配。由于序列比析取符号具有更高的优先性,所以/the|any/与the或any相匹配,而不与thny匹配。

    模式有时可能具有歧义。正则表达式应该总数尽其可能与其中最长的符号串相匹配。

    3 一个例子

   我们来设计关于价格的正则表达式。下面是一个美元符号$后接一个数字符号串的表达式,如下:

   /$[0-9]+/

  现在我们需要处理美元中的小数部分,可以在上述表达式后加小数点和两个数字。正则表达式如下:

  /$[0-9]+/.[0-9][0-9]/

  这样的表达式只能表示$199.99,而不能表示$199.我们需要把小数部分设成可随意选择的,并且确定单词的边界。正则表达式如下:

     //b$[0-9]+(/.[0-9][0-9])?/b/

 

4 高级算符

    还有一些有用的正则表达式高级算符,使用这些替换名可以节省打字的工作量。除*和+之外,我们还可以使用花括号{}括起来的数字作为计数符。例如,正则表达式/{3}/表示“前面的字符或表达式正好出现3个”,这样/a/.{24}z/就表示a后面跟随着24个点,再跟着一个z。

                             

5正则表达式中的替换、存储器

  正则表达式的一个重要用途是替换(substitution),例如,Perl的替换运算符s/regexp1/regexp2/可把一个正则表达式描述的符号串替换成另一个用正则表达式描述的符号串:

                      s/colour/color/

我们经常需要引用与某个模式相匹配的符号串中的特定部分。例如,假定要把文本中的所有整数的两侧加上尖括号,具体地说,要把the 25 boxes替换成the<25>boxes。我们只要引用相应的整数,就可以很容易地在它的两侧加上尖括号。为此,在第一个模式(即整数)的两侧加上圆括号"("和")",然后在第二个模式中使用数字符号"/1"以便回过头去参照第一个模式:

              s/([0-9]+)/</1>

圆括号和数字也可以用来说明某个符号串或表达式在文本中出现两次。例如,假设我们要查找模式“the Xer they were,the Xer they will be”,想让其中的X指同一个字符串。这时,我们在第一个X的两侧加圆括号,并且用数字算符"/1"替换第二个X:

     /the (.*)er they were,the /1er they will be/

这里的“/1”可以与圆括号中的项相匹配的任何符号串来替换。因此,与这个正则表达式相匹配的符号串是the bigger they were,the bigger they will be,而不是the bigger they were,the faster they will be 。这样的数字算符也可以与其他数字一起使用。如果要匹配的是两个不同的圆括号中的符号串集合,/2就表示第二个圆括号中的符号串集合。例如

                /the (.*)er they (.*), th /1er they /2/

就可以匹配the bigger they were,the bigger they were,但是这个表达式不能匹配the bigger they were,the bigger they will be。

     这样的数字存储器称作为寄存器(register)。例如,寄存器1、寄存器2、寄存器3等。这样的存储器特性不是每种正则表达式都具备的,但这常常是正则表达式的“扩充”特性。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值