perl学习(7) 正则表达式

来源:互联网 发布:怎么样在淘宝网领金币 编辑:程序博客网 时间:2024/06/06 00:24

我认为正则是任何脚本语言的 重点,perl也是必须的,不过基本规则是一致。

1. 正则表达式

默认是对$_ 进行匹配,如下:

$_ = “I dream a millinon”;

if(m/eam/)

{

         print “match success!” ;

}

可以通过=~进行绑定,符号成为绑定符,优先级非常高

my $word = “let me become a million”;

if( $word =~ m/^let/)

{

         print “match success!”

}

普配模式可以被变量替换。

my $model = “[a-z]+_[0-9]+/.log”;

my @hash_c ;

while(<STDIN>)

{

         if(m/$model/i)

         {

                   $hash_c{“$_”} = “1”;

         }

} 

1.1.元字符

.        单个字符,不包括 \n

/        转义

*       前面的字符重复0或多次

?       前面的字符重现0或一次

+       前面的字符重复1或多次

()       分组,扩成整体

|       or

[]       内部中的一个字符

\d     0-9中的一个

\w    任意一个字母、数字、下划线

\s      一个空格

^                     [^\d]         非数字     [^\w]                  非字符

{n,m}         前一个对象重复的次数 

1.2.修饰符

修饰符放在m//匹配的后面,m//匹配可以为任何对应符号。

/i       大小写无关           if(/yes/i) {#大小写无关

/s      使用时.可以匹配任何字符  if(/Barney.*Fred/s)

/x    允许你在模式中加入任何数量的空白

/g  全局的

/m   允许换行匹配 

说明三个修饰符可以组合使用

if (m{barney.*red}six)

{

       print “That string mentions Fred after Barney!\n”;

}

#修饰符包括包括/s, /i, /x

#可以包含任何字符 

1.3.位置符

perl里专业词为锚定,anchoring

^       开始        /^fred/

$       结尾        /rock$/

\b    词界

1.4.匹配变量

在模式中使用括号,匹配到的字符串中与括号对应的部分可以被取出来。

my $dino = "I fear that I'll be extinct after 1000 years.";

if ($dino =~ /(\d*) years/) {

    print "That said '$1' years.\n"; # 1000

}

输出为:That said '1000' years. 

这些匹配变量的值会保持不变,直到下一个模式成功匹配为止,所以如果使用这些内存值,必须良好的保存:

if($wilma =~ /(\w+)/){

       my $wilma_word = $1;

      

} 

三个内置匹配变量:

$`         匹配字符串之前的部分

$&         匹配的字符串

$’           匹配字符串之后的部分

如果你使用了这三个自动匹配变量中的任意一个,无论在程序的什么地方,其它地方的正则表达式的运行数度会变慢一些,尽量不使用。 

1.5.优先级

优先级从高到低分别为:    

()      

数量词    

锚定和序列    

| 

1.6.处理文件

1.6.1.   使用s///进行替换

m// 这个模式匹配看作同文字处理器的查询(search类似的功能

s ///操作的则类似于“查询并替换(search and replace)”

实例 :

#! /usr/bin/perl

use strict ;

use warnings ;

#匹配

my $dino = "I fear that I'll be extinct after 1000 years.";

if ($dino =~ /(\d*) years/) {

    print "That said '$1' years.\n"; # 1000

}

#默认下的模式替换

$_ = $dino ;

s/(\d*) years/ 25 minutes/;

print $_ ,"\n";

#

$dino =~ s/(\s\d*\syears)/\U$1-five days/;

print $dino,"\n";

 

结果:

1.  修饰符/U 将字符全部转换为大写

2.  $1即匹配变量

3.   

s///值进行一次替换,无论是否还有地方还能匹配上,使用修饰符/gs///将不相重叠的所有匹配上的部分都进行替换。

如同m//qw//一样,我们也可以改变s///的分隔符。但这里使用了个分隔符:

s{fred}{barney};

s[fred](barney);

s<fred>#barney#;

 

1.6.2.  split操作

开头的空元素会被返回,但结尾的空元素被丢弃 

@fields = split /:/,“abc:def::g:h”; 

my $some_input = “This is a \t test.\n”;

my @args = split /\s+/, $some_input; #(“This”, “is”, “a”, “test.”)

1.6.3.  join函数

join 函数不使用模式,但它完成同split相反的操作

join 的第一个参数是字符串,而非模式

如果列表中元素个数小于2,则不会有粘合的元 

my $x = join“:”, 4, 6, 8, 10, 12; #$x“4:6:8:10:12”

my $y = join “foo”, “bar”; #得到“bar” 

my @empty; #空数组

my $empty = join “baz”, @empty; #没有元素,因此为空串

 

1.6.4.  列表存储分割值

使用列表或者hash结构存储分割值 

#! /usr/bin/perl

use strict ;

use warnings ;

my $text = "Fred dropped a 5 ton granite block on Mr. Slate";

my @words = ($text =~ /([a-z]+)/ig);

print "Result: @words\n";

 

my $data = "Barney Rubble Fred FlintstoneWilma Flintstone";

my %last_name = ($data =~ /(\w+)\S+(\w+)/g);

while((my $key,my $value) = each %last_name)

{

    print "$key=>$value\n" ;

}

结果:

说明:

 

 

 1.7.更强大的正则表达式

1.7.1.  贪婪和非贪婪

贪婪模式:

在使用修饰匹配次数的特殊符号时,有几种表示方法可以使同一个表达式能够匹配不同的次数,比如:"{m,n}", "{m,}", "?", "*", "+",具体匹配的次数随被匹配的字符串而定。这种重复匹配不定次数的表达式在匹配过程中,总是尽可能多的匹配。

 

比如,针对文本 "dxxxdxxxd",举例如下:

表达式

匹配结果

(d)(\w+)

"\w+" 将匹配第一个 "d" 之后的所有字符 "xxxdxxxd"

(d)(\w+)(d)

"\w+" 将匹配第一个 "d" 和最后一个 "d" 之间的所有字符 "xxxdxxx"。虽然 "\w+" 也能够匹配上最后一个 "d",但是为了使整个表达式匹配成功,"\w+" 可以 "让出" 它本来能够匹配的最后一个 "d"

由此可见,"\w+" 在匹配的时候,总是尽可能多的匹配符合它规则的字符。虽然第二个举例中,它没有匹配最后一个 "d",但那也是为了让整个表达式能够匹配成功。同理,带 "*" "{m,n}" 的表达式都是尽可能地多匹配,带 "?"的表达式在可匹配可不匹配的时候,也是尽可能的 "要匹配"。这种匹配原则就叫作 "贪婪"模式。

 

非贪婪模式:

在修饰匹配次数的特殊符号后再加上一个 "?"号,则可以使匹配次数不定的表达式尽可能少的匹配,使可匹配可不匹配的表达式,尽可能的 "不匹配"。这种匹配原则叫作 "非贪婪"模式,也叫作 "勉强"模式。如果少匹配就会导致整个表达式匹配失败的时候,与贪婪模式类似,非贪婪模式会最小限度的再匹配一些,以使整个表达式匹配成功。

 

举例如下,针对文本 "dxxxdxxxd"举例:

表达式

匹配结果

(d)(\w+?)

"\w+?" 将尽可能少的匹配第一个 "d" 之后的字符,结果是:"\w+?" 只匹配了一个 "x"

(d)(\w+?)(d)

为了让整个表达式匹配成功,"\w+?" 不得不匹配 "xxx" 才可以让后边的 "d" 匹配,从而使整个表达式匹配成功。因此,结果是:"\w+?" 匹配 "xxx"

 匹配过程:

贪婪模式,匹配到最大,逐步回撤

非贪婪模式,匹配到最小逐步放大 

1.7.2.  更新文件

关键是 特殊变量$^I

 

看一个例子:

#! /usr/bin/perl -w

use strict;

chomp(my $date = `date`);

$^I =".bak";

 

while(<>)

{

    s/^Author:.*/Author: Randal L. Scharwartz/;

    s/^Phone:.*\n//;

    s/^Date:.*/Date: $date/;

    print;

}

运行:

产生文件data.txt.bak

说明:

内容被写入到新文件,新文件是源文件加一个后缀,后缀即为$^I存放的值

如果没有这个变量,那内容将被输出到STDOUT

 

如果操作很多个文件的时候,将是非常简单。

 

 

这个也可以在命令行实现:

$perl –p –i.bak –w –e ‘s/Randall/Randal/g’fred*.dat

 

原创粉丝点击