用户名: 密   码:
   飞诺网 加入收藏
飞诺网 网站开发 VBScript ASP Asp.net Jsp php XML CGI-Perl 搜索引擎 ajax web技术
CGI-Perl系列教程 CGI-Perl技术文档 CGI-Perl实例

您当前的位置:飞诺网 >>  网站开发 >>  CGI-Perl >> CGI-Perl实例

Perl正则表达式讲解,真的非常详细

www.diybl.com    时间 : 2008-09-12  作者:佚名   编辑:辉辉 点击:   [ 评论 ]

9.3.11匹配和g运算符

修饰符(x、i、s和e)的工作与匹配运算符m//相同;,然而有一个明显的改变是g运算符的工作方式方面,而且读者将频繁地使用到它。

正如我们前面所看到的,在替换中的g运算符意味着要替换正则表达式的每一个实例。

然而,这在匹配环境下是毫无意义的,反向引用表明一个且仅有一个匹配。因而,Perl在m//中以不同于s///的方法使用g运算符。

Perl给g运算符连结—个迭代程序。当用$string=~m" " g匹配一次时,Perl会记住匹配发生的地方。这意味着读者可以使用迭代程序来匹配离开的地方。当Perl遇到字符串结尾时,重新设置迭代程序:

$line = " hello stranger hello friend hello sam";

while($line=~ m" hello (\w+)" sg)

{

print " $l\n";

}

这会输出:

stranger

friend

sam

接着退出,原因是内部的迭代程序到达表达式的尾部。这里有一个提示,如果读者正在使用g修饰符,那么对通过赋值匹配的变量的任何修改都会导致重新设置迭代程序。

$line = " hello";

while($line=~ m" hello" sg)

{

$line = $line;

}

这是一个无限循环!所以在匹配时要约束自己和避免修改字符串。(做一份拷贝来替代它)

 

9.3.12修饰符和环境

如果在开始学习本章之前读者不熟悉Perl正则表达式,那么读者的头脑中可能会漂浮着同的修饰符、方法、特殊字符等等。让我们花点时间来看看使用正则表达式的不同形式,然后介绍一些常用的正则表达式例子结束本章。

这一切都与环境有关。记住,在Perl中,环境是王者,如果读者注意它,则通过辨识不同表达式所处的环境就可以做许多强有力的事情。我们简单地“结晶”一些我们到现在为止所见到的形式,然后增加几个新的。

1.标量环境下的替换(无修饰符) 这种情况的代码看起来如下所示:

if($string =~ s" a" b") {print:" Substituted Correctly" ;}

程序会打印Substituted Correctly,当字符串实际上匹配后给if返回l。同时它也会把a的所有实例替换为b。

2.在标量环境下的替换(g修饰符)

这种情况下返回成功匹配的次数。使用这种方法,如果读者输入以下代码:

($string =~ s" a" b" g) == ($string =~ s" a" b" g)

Perl将告诉读者是否$string中有与$string2中相同数量的a,同时进行替换。如果读者愿意可以在整个文件上使用它:

undef $/;

my $fh = new FileHandle(" File1");

my $fh2 = new FileHandle(" File2");

(($line = <$fh>) =~ s" a" b") == (($line2 = <$fh2>) =~ s" a" b");

这会计算两个文件中的a数,当再做替换时比较它们。

3.在数组环境下的替换(无修饰符)和数组环境下的替换(g标识符)

这两个较烦人。它们实际上做与标量环境下替换相同的工作。

4.在标量环境下的匹配(无修饰符)

这与在标量环境下不带修饰符的替换相同。如果读者输入:

if($line =~ m"a") {print "Matched an a!\n" ;}

它只检查在$line中是否有一个a。如果输入:

if($line=~m" \b(\w+)\b"){print " $l\n";}

这会检查在$line中是否有单词,接着把它存放在$1中,打印它。同时:

($line=~m" \b(\w+)\b")&&(print " $l\n";);

做同样的工作,仅使用短路来打印它。

5.在数组环境下的匹配(无修饰符)

这会匹配正则表达式能匹配的第一个位置,接着简单地把反向引用放入一个可快速访问的表中。例如:

($variable,$equals,$value) = ($line = ~m" (\w+)\s*(=)\s*(\w+)");

该代码取到第一个引用(\w+),使之成为$variable;取到第二个引用(=)使之成为$equals;然后取到第三个引用(\w+),使之成为$value。

6.在数组环境下匹配(g修姊符)

取到正则表达式,尽可能多地应用它.然后把结果放人到由所有可能匹配组成的数组中,

例如:

$line = '1.2 3.4 beta 5.66';

@matches = ($line =~m" (\d*\.\d+)" g);

将使@matches等于1.2,3.4,5.66。g修饰符完成迭代,首先匹配1.2,其次是3.4,第三是5.6。同样:

undef $/;

my-$FD= new FileHandle(" file");

@comments = (<$FD> =~m" /\*(.*?)\*/");

将生成一个包含文件$fd中所有注释的数组。

7.标量环境下的匹配(g修饰符)

最后,如果在标量环境下使用匹配运算符,那么读者得到与在正则表达式世界中甚至是在Perl世界中完全不同的行为。这就是我们谈到的“迭代”行为。如果输入以下代码:

$line = " BEGIN <data> BEGIN <data2> BEGIN <data3>";

while($line =~ m" BEGIN(.*?)(?=BEGIN|$)" sg)

{

push(@blocks, $l);

}

这将匹配以下的文本(粗体),随后在接下来的while迭代中把它加载@blocks中。

BEGIN <data> (%)BEGIN <data2> BEGIN <data3>

BEGIN <data> BEGIN <data2>(%) BEGIN <data3>

BEGIN <data> BEGIN <data2>(%) BEGIN <data3>

通过(%)我们已经表明了每次迭代开始匹配的位置。注意本例中(?=)的用法。它是匹配正确方式所必须的;如果不用它,匹配程序将会被放在错误的地方。

1 2 3 4 5 6 7 8 9 10 11 12
如果图片或页面不能正常显示请点击这里
CGI-Perl实例推荐文章

文章评论