码迷,mamicode.com
首页 > 其他好文 > 详细

perl学习笔记——正则表达式

时间:2015-07-23 09:26:58      阅读:116      评论:0      收藏:0      [点我收藏+]

标签:

正则表达式

简单模式:匹配$_中的内容,只需要将模式写在一对斜线(/)中就可以了。

如:#!/usr/bin/env perl

use 5.010;

$_="yabba dabba doo";

if(/abba/){

  say "it matched!";

}

关于元字符

shell中的差不多:

.==>任意字符;

*==>重复0次及其0次以上;

+==>重复一次及一次以上;

?==>重复0次或一次;

模式分组

在正则表达式中,用圆括号()对字符串分组。

反向引用的写法是在斜线后面接上数字编号,如\1 \2这样。相应的数字表示对应顺序的捕获组。

下面举例说明:

 技术分享

反向引用也不必进接在对应的捕获组的后面。下面的模式或匹配y后面的4个连续的非换行符,并用\1反向引用表示匹配d后也出现的4个字符的情况。

$_=”yabba dabba doo”;

If (/y(....) d\1/){

Print “It matched the same after y and d!\n”;

}

也可以用多个括号来分成多组,每个组都可以有自己的反向引用。

$_=”yabba dabba doo”;

If (/y(.)(.)\2\1/){ #匹配 ‘abba’

Print “It matched the same after y and d!\n”;

}

那么如何区分哪个括号是第几组呢?Larry给出的解释:只要一次点算左括号(包括嵌套括号)的序号就OK了。如:

$_=”yabba dabba doo”;

if (/y((.)(.)\3\2) d\1/){

  print “It matched the same after y and d!\n”;

}

拆开:(    #第一个括号

(.) #第二个括号

(.) #第三个括号

\3

\2

)

上面遗留的问题:

$_=”aa11bb”;

If (/(.)\111/){

  print “It matched!\n”;

}

原本是打算匹配aa11 ,现在好了。Perl将其理解为匹配第111组括号,根本找不到这个括号,报错。

解决方法:\g{1}  就可以消除反向引用与模式的直接量部分的二义性。

use 5.010;

$_=”aa11bb”;

If (/(.)\g{1}11/){

  print “It matched.”.”\n”;

}

而且用\g{N}还有一个好处就是N可以是负数,也就是说可以为-1 -2等。表示的意思就是倒数或者说相对位置。

-1 表示离\g{-1}最近的第一个左括号;

-2 表示离\g{-2}最近的第二个左括号;

use 5.010;

$_=”aa11bb”;

if (/(.)(.)\g{-1}11/){

  print “It matched.”.”\n”;

}

择一匹配

|

如:/fred(and|or)barney/

字符集

[a-zA-Z]

[^a-zA-Z]

字符集的简写

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

$_=’The HAL-9000 requires authorization to continue.’;

if (/HAL-[\d]+/){

  say “It matched.”

}

修饰符/a,写在正则表达式末尾,表示按照ASCII的语义展开(Perl 5.14引入的修饰符)

use 5.014;

$_=’The HAL-9000 requires authorization to continue.’;

If (/HAL-[\d]+/a){ #俺老的ASCII字符解释

  say “It matched.”

}

说明:引入/a的主要原因是因为\d 现在的语义不仅再是[0-9]这个范围了,它还表示了很多比较特殊的数字符。

\s能匹配以下5个空白字符:换页符\f 水平制表符\v 垂直制表符\h 回车符\n 空格符\p

use 5.014;

if (/\s/a){ #按老的ASCII字符语义解释

  say “The string matched ASCII whitescape”;

}

\R匹配断行符,无论是\r\n还是\n都能匹配。

\w匹配单词字符,所谓单词其实是[a-zA-Z0-9]组成的。

反义简写

\D 表示[^\d]

\W 表示[^\w]

\S  表示[^\s]

这些简写既可以做为模式里独立的字符集,也可以作为方括号里字符集的一部分。比如:/[\dA-Fa-f]/

 

用正则表达式进行匹配

m//进行匹配

前面所讲的用//写法表示模式,比如/fred/事实上是m//的特例。

通用像qw //一样,分隔符也是可选的如:m{fred} m <fred>

模式修饰符

/表示按照ASCII的语义展开

/i  表示进行大小写无关的匹配

print “would you like to play a game?”;

chomp($_=<STDIN>);

If(/yes/i){ #大小写无关的匹配

say “i like too.”;

}

/s  表示匹配任意字符;

在很多情况下(.)是没有办法匹配到换行符的,但如果字符串中含有换行符,而你有希望匹配这些换行符,那么就可以用/s修饰符完成。(实现原理是,Perl会将点号转换成字符集[\d\D]来处理,就是说会匹配任意字符)

$_=”I saw Barney\n down at the bowling alley\nwith Fred\nlast night.\n”;

If (/Barney.*Fred/s){

Print “That string mentions Fred after Barney\n”;

}

出现的问题:/s会把模式中所出现的.都修改成能匹配任意字符,那如果我们只是想其中几个匹配任意字符呢?可以用\N

/x  表示加入空白符;

技术分享

举例如下:

#!/usr/bin/env perl

use 5.010;

$_="fred";

if(/fre  d/x){

  say "it matched."

}

技术分享 

当然上面的修饰符都可以组合:

if(/barney.*fred/is){#同时使用/i/s

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

}

 

perl学习笔记——正则表达式

标签:

原文地址:http://www.cnblogs.com/lukexwang/p/4669402.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!