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

Perl Learning 6 Regular Expression

发布时间:2020-12-15 23:42:21 所属栏目:大数据 来源:网络整理
导读:正则表达式在 Perl 里面通常也叫做模式 (pattern) 是用来表示匹配(或不匹配)某个字符串的特征模板。注意不要把正则表达式和 shell 的“文件名匹配模式”(又称为 glob ,文件名通配)混为一谈。在 Unix?shell 中键入 *.pm 来匹配所有以 .pm 结尾的文件就是


正则表达式在Perl里面通常也叫做模式(pattern)是用来表示匹配(或不匹配)某个字符串的特征模板。注意不要把正则表达式和shell的“文件名匹配模式”(又称为glob,文件名通配)混为一谈。在Unix?shell中键入*.pm来匹配所有以.pm结尾的文件就是典型的文件名通配。

简单匹配模式:若模式匹配的对象是$_的内容,只要把模式写在一对斜线中就行。


Unicode属性:Unicode字符能够理解自身含义,它们不只是简单的字节序列。每个字符除了字节组合之外,还附带着属性信息。若要匹配某项属性,只需要把属性名放入p{property}里面。比如有很多字符属于空白符(whitespace),相应的属性名为Space,所以要匹配带有这类属性的字符,可以用p{Space}表示。我们还能匹配不包含特定属性的字符,只要把小写的p改为大写,就表示否定意义,匹配指定属性以外的字符。

?

元字符:点号(.)是能匹配任意一个字符的通配符,换行符(“n”)除外。注意:在任何元字符前面加上反斜线,就会使它失去元字符的特殊作用。

?

简单的量词:?星号(*)用来匹配某条目零次或多次的。.*会匹配任意字符零次到无限多次。加号会匹配前一个条目一次以上:/fred+barney/会匹配在fredbarney之间用空格隔开并且只用空格隔开的字符串(空格不是元字符)。问号(?)表示前一个条目是可有可无的。

?

模式分组:小括号的作用是对字符串分组,模式/(fred)+/会匹配项fredfredfred这样的字符串。圆括号同时也使得重新使用某些字符串成为可能。我们可以用反向引用来引用圆括号中的模式所匹配的文字,这个行为我们称为捕获组。反向引用的写法是在反斜线后面接上数字编号,比如12这样。相应的数字表示对应顺序的捕获组。

使用圆括号包围的点号可以匹配任意非换行字符。我们可以用反向引用1来再次匹配刚刚在圆括号中匹配的任意字符:



(.)1表明需要匹配连续出现的两个同样的字符。反向引用不必紧接在对应的捕获组括号后面。下面的模式会匹配y后面的4个连续的非换行符,并用1反向引用表示匹配d后也出现这4个字符的情况:



也可以用多个括号来分成多组,每组都可以有自己的反向引用。我们可以用括号定义一个非换行字符的捕获组,后面跟着一个非换行字符的捕获组。然后用反向引用21来构成有趣的回文模式,比如abba



Perl?5.10开始支持一种新的反向引用写法。不再只是简单的用反斜线和组号,而是用g{N}这种形式。其中N是想要反向引用的组号。

$_ = "aa11bb";
if (/(.)g{1}11/){
	print "It matched 11! n";
}

g{N}的写法的额外好处是,我们甚至可以用负数。相比指定捕获组的绝对编号,相对反向引用会更加有趣。这样我们可以用-1来做同样的事情:

$_ = "aa11bb";
if (/(.)g{-1}11/){
	print "It matched 11! n";
}<pre name="code" class="plain">

 

这样若要在模式中加入更多的内容,就不必总是修改反向引用的编号了。因为要加入另外一个捕获组,就会导致所有绝对编号的反向引用失效,而相对反向引用则不会,因为它使用的是相对于自己的位置,而不是绝对编号:

$_ = "xaa11bb";
if (/(.)(.)g{-1}11/){
	print "It matched 11! n";
}

择一匹配:竖线(|通常可以读成或,意思是要么匹配左边的内容,要么匹配右边的内容。现在可以使用/fred(|t)+barney/这样的模式来匹配fredbarney之间出现一次以上空格、制表符或两者混合的字符串。加号表示重复一次或者更多,每次只要有重复,(|t)就可能匹配空格或制表符。若要求fredbarney之间的字符必须都一样,你可以把上述模式改成/fred(+|t+barney/),这样,中间的分隔符就一定得全是空格或全是制表符。

?

字符集:指的是一组可能出现的字符,通过写在方括号表示。它只匹配单个字符,但可以是字符集中列出的任意一个。我们可以用连字符(-)表示始末范围,这样[a-zA-Z]可以匹配52个大小写字母中的任意一个。

?

字符集的简写。表示任意一个数字的字符集的简写是d

$_ = "The Hal-9000 requires authorization to continue";
if (/Hal-[d]+/){
	 print 'The string mentions some model of Hal computer.';
}


当我们需要严格按照ASCII的范围来匹配数字字符时,可以选用a,写在正则表达式末尾。s能匹配任意空白符,所以效果大抵等同于Unicode属性p{Space}R能匹配任意一种断行符。

反义简写:引入它们的大写版本来表示否定意义。这些简写既可以作为模式里独立的字符集,也可以作为方括号里字符集的一部分。/[dA-Fa-f]+/可以用来匹配十六进制数字。[dD]表示任何数字非数字,也就是说,它会匹配任意字符。




第一题:

<span style="font-size:12px;">$_ = <STDIN>;
if (/fred/){
	print;
}</span>

俺写的只能一行一行判断,答案里面加上了while循环

while(<>){
	if(/fred/){
		print;
	}
}

就是能够直接识别你当前输入的行中是否有fred,有则复制没有则继续。


我们发现Fred没有接受,而后两者接受了,正则表达式对大小写还是很敏感的。


习题二:改为能接受Fred的话,将第一题中的/fred/改为/[f|F]red/即可

习题三:

while(<>){
	if(/./){
		print;
	}
}


发现输入Mr.Slate的时候会输出。

习题四:

while(<>){
	if (/[A-Z]+/){
		print;
	}
}

该代码对全大写的单词也会打印。在[A-Z]后面再加上[a-z]即可

第五题:

while(<>){
	if (/(S)g{-1}/){
		print;
	}
}


第六题:

while(<>){
	if(/[fred.*wilma]/){
		print;
	}
}


我看了下答案,它是这么写的(/wilma.*fred|fred.*wilma/)。我觉得比我写的要麻烦些。但是经过验证我发现我写的还是有问题,因为我输入fred的时候也可以打印,不符合题目要求。[]的使用只是提供了一个集合。


总结:这段时间一直在忙小学期,做一个推荐系统,我们的框架是由php+python搭出来的,之后等成绩出来了就把我们的项目讲一下。之后的日子就继续学perl以及Verilog和VTR


正则表达式在 Perl 里面通常也叫做模式 (pattern) 是用来表示匹配(或不匹配)某个字符串的特征模板。注意不要把正则表达式和 shell 的“文件名匹配模式”(又称为 glob ,文件名通配)混为一谈。在 Unix?shell 中键入 *.pm 来匹配所有以 .pm 结尾的文件就是典型的文件名通配。

(编辑:李大同)

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

    推荐文章
      热点阅读