加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

perl学习(7) 正则表达式

发布时间:2020-12-16 00:08:41 所属栏目:大数据 来源:网络整理
导读:我认为正则是任何脚本语言的 重点,perl也是必须的,不过基本规则是一致。 1. 正则表达式 默认是对 $_ 进行匹配,如下: $_ = “I dream a millinon”; if(m/eam/) { ???????? print “match success!” ; } 可以通过 =~ 进行绑定 , 符号成为绑定符,优先级

我认为正则是任何脚本语言的 重点,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/(sd*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: @wordsn";

?

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=>$valuen" ;

}

结果:

说明:

?

?

?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

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读