由于公司需要,本人最近在学习Perl这种脚本语言,本文是我在学习Perl的过程中总结出来的一些心得和笔记,希望能够帮助也在学习Perl的各位同僚。废话不多说直接上干货!!!
————————————————————————— 干货分割线 ———————————————————————————
Perl变量$_常常用于Perl需要默认值的时候.
模式表示方式:m/simon/
Exp:
If(m/Piglet/){
#模式Piglet在$_中
}
在这个模式中,除非字符是个元字符,否则每个字符均与自己相匹配。大多数“标准”字符均与自己相匹配,这些字符包括A至Z、a至z和数字。元字符是指改变了模式匹配运行特性的那些字符。下面是元字符的列表:
^ $ () \ | @ [ { ? . + *
在你的模式中,如果想要匹配元字符的原义值,只需要在元字符的前面加上一个反斜杠即可,如下所示:
m/I won \$10 at the fair/;
前面我们已经讲过模式匹配运算符通常用m / /来表示。实际上,在许多情况下,当模式中包含斜杠( /)时且模式的结尾则可能与模式内的斜杠相混淆,可用另一个字符来代替它,因此括号里面的斜杠的前面必须加上反斜杠,这给阅读带来了不便,因此perl规定可以用你想要的任何其他字符来代替斜杠,如下面这个例子所示:
If(m,Waldo,){
Print “found waldo.\n”;
}
如果将模式括起来的字符(称为界限符)是斜杠,那么编写模式匹配代码时也可以不带m。因此,也可以将m / C h e e t o s写成/ C h e e t o s /。通常情况下,除非需要使用不是斜杠( / /)的其他界限符,否则,可以只使用斜杠而不使用m来编写模式匹配代码。变量也可以用在正则表达式中。如果在正则表达式中看到一个标量变量, P e r l首先计算该标量,然后查看正则表达式。
Exp:
#!/usr/bin/perl
$pat = <STDIN>; chomp $pat;
$_ = "The phrase that pays";
if(/$pat/){
print "\"$_\" contains the pattern \"$pat\"\n";
}
元字符的介绍:
.(圆点):用于匹配除了换行符外的任何单个字符.如/p.t/可匹配pot,pit,carpet.’.’要求存在一个字符,但不能有更多字符.当普通字符的前面加上反斜杠后,它就变成了元字符。正如你在第2学时中看到的字符串那样,有些字符的前面加上反斜杠后,它在字符串中就具备了特殊含义。在正则表达式中,所有这些字符几乎代表相同的值,如表6 - 1所示:
通配符:
元字符+用于使前面的字符与后面的字符至少匹配一次,也可以任意次地进行匹配,并且仍然拥有匹配的表达式。因此, / d o + g /将能够与下面的字符串匹配:
Hounddog,hotdog doogie dooooooogdoog,
但不能与下面的字符匹配:
Badge,doofus,Doogie(区分大小写)
元字符*使得前面的字符可以进行0次或多次匹配。换句话说,模式/ t * /可以进行任意次的匹配,但是,如果没有匹配的字符存在,这也没有问题。因此,/ c a r * t /将能够与下面的字符匹配:
carted,cat,carrrt
但不能与下面的字符匹配:
Carrot,carl,caart
元字符?:用于使前面的字符进行0次或一次匹配(但是不能超过一次)。
元字符{}:使用{}可以对你制定的字符串进行指定次数的匹配.格式如下:
Pat{n,m};
N为匹配的最小次数,m为最大次数.pat是你试图量化匹配的字符或字符组,n,m可以分别省略,但不能同时省略,例如:
/x{5,10}/ x至少出现5次最多出现10次
/x{5,}/
/x{0,10}/
/x{5}/ #正好出现5次
通配符. *:可以用它来匹配任何东西,通常是你感兴趣的其他两样东西之间的任何东西。例如/ f i r s t . * l a s t /。这个模式设法匹配单词f i r s t,再匹配它后面的任何东西,然后匹配单词l a s t。请观察/ f i r s t . * l a s t /是如何匹配下面的字符串的:
first then last; The good players get picked first, the bad last. The first shall be last, and the last shall be first.
P e r l的正则表达式拥有这样一个工具,它称为字符类。若要编写一个字符类,可以用方括号[ ]将这些字符括起来。进行匹配时,字符类中的所有字符被视为单个字符。在一个字符类中,可以设定字符的范围(在范围有意义的时候),方法是在上限与下限之间加一个连字符。下面是一些例子:
由于]、^和-等字符都是字符类中的特殊字符,因此,如果按照字符的原义来匹配字符类中的这些字符,就要使用某些规则。若要匹配字符类中的原义字符^,必须确保它不出现在字符类中的第一个字符的位置上;若要匹配字符],你既必须将它放在字符类中的第一个字符位置上,也可以在它的前面加上一个反斜杠(例如/[abc\ ] ]/);若要将一个原义连字符( -)放在字符类中,你只需要将它放在字符类中的第一个字符位置上,或者在它的前面放一个反斜杠。
| 字符:在|两边进行选择,例 如:
If(/dogs|cats/){
Print “$_ contains a pet \n”
}
正确的选择模式为: /(fr|b|cl|fl)og/; (不同部分用括号)
$_ = “apple is red ”;
($fruit ,$color ) = /(.*)\sis\s(.*)/;
在上面这个代码段中,该模式先对任意对象(用(.*)来表示,作为一个组)进行匹配,然后对白空间(\s)进行匹配,再对单词i s进行匹配,然后匹配一个白空间(用\s表示),再对任意对象(用(.*)来表示,也作为一个组)进行匹配。这两个分组的表达式返回左边的列表,并赋予$ f r u i t和$ c o l o r。
Exp:
$_ = "banana is yellow";
if(($fruit,$color) = /(.*)\sis\s(.*)/){
print "fruit is $fruit,color is $color\n";
}
输出:
位置通配符:
插入记号( ^):正则表达式开头的插入记号告诉正则表达式只匹配一行开头的字符。例如, / ^ v i d e o /只匹配单词v i d e o,如果它出现在一行的开头的话。
美元符号( $):正则表达式结尾处的美元符号能够使模式只匹配一行结尾的字符。例如/ e a r t h $ /用于匹配e a r t h ,不过它只能位于行尾。
替换运算符S/// :
s/searchpattern/replacement/;替换运算符用于默认搜索$ ,找出searchpattern, 并且用r e p l a c e m e n t来替换整个匹配的正则表达式。该运算符返回匹配的数量或进行替换的数量,如果没有进行任何匹配,则返回0。
Exp:
$_ = "Our house is in the middle of our street";
s/middle/end/;
print $_;
输出:
替换运算符也可以使用非斜杠( /)的界限符,使用的方法与匹配运算符相同。只需要直接在s的后面加上你想要的界限符即可,如下所示:
S#searchpattern#replacement#;
连接运算符=~:该运算符不进行赋值,它只是取出右边的运算符,并使它对左边的变量进行操作。整个表达式拥有的值与使用$ 时所拥有的值是相同的,如果要对非$_的变量使用匹配运算符和替换运算符,则必须将它们与该变量连接起来。为此可以使用连接运算符= ~
$weight =”185 lbs”;
$weight =~s/lbs//;
在模式匹配中,若不考虑大小写字母,可以使用以下代码:
/[Mm][Aa][Bb]/; #笨拙写法
替换运算符(s / / /)和匹配运算符(m / /)能够在匹配正则表达式时不考虑大小写字母,
如果匹配项的后面跟一个字母i的话,例如:
/macbeth/i; #不区分大小写
上面这个例子可以对M a c b e t h进行匹配,无论它是使用大写字母、小写字母还是大小写混合字母(M a C b E t H)。
Exp:
$f = "one fish,two frogs,red fred,blue foull";
@F = $f =~ m/\W(f\w\w\w)/g;
#@F = $f =~ m/\W(f\w\w)/g; #3ge\w
#@F = $f =~ m/\W(f\w\w)/; #无g
print @F;
输出:
该模式首先匹配一个非单词字符,然后匹配字母f,接着匹配4个单词字符。字母f和4个单词用括号分组。该表达式被计算后,变量@ F将包含4个元素,即f i s h、f r o g、f r e d和f o u l。在标量上下文中,修饰符g使得匹配操作迭代通过整个字符串,为每个匹配操作返回真,当不再进行更多的匹配操作时,返回假.
Exp:
$letter = 0;
$phrase = "What's my line?";
while($phrase =~/\w/g){
$letter++;
}
print $letter;
输出:11
Ps:what’s算一个单词且’不算.w h a t s m y l i n e共11个
Grep:查找数组中特定元素的函数,语法:
Grep expression,list
Grep block list
Exp:
@dogs = qw(greyhound bloodhound terrier dasfhound mutt chihuahua);
@hounds = grep/hound/,@dogs;
print @hounds;
输出:输出@dogs中包含Hound的元素
@dogs的每个元素被依次赋予$_.然后根据$_对表达式/hound/进行测试.返回真的每个元素被grep返回,并存放在@hounds中.首先,在表达式中, $ 是对列表中的实际值的引用。如果修改$ ,就会改变列表中的原始元素.
g r e p不一定必须与模式匹配或替换运算符一道使用,它可以与任何运算符一道使用。下面这个例子用于检索长度超过8个字符的犬名:
@longdogs = grep length($_) > 8,@dogs;
m a p函数:该函数的句法与grep基本相同,不过它的表达式(或语句块)返回的值是从map返回的,而不是$_的值。可以使用map函数,根据第一个数组来产生第二个数组.
Exp:
print "请输入单词:\n";
@input = <STDIN>;
chomp;
@words = map{split' ',$_} @input;
print @words;
在这个例子中,数组@ i n p u t的每个元素(作为$ 传递给语句块)均用空格隔开。这意味着@ i n p u t的每个元素均产生一个单词列表。该列表存放在@ w o r d s中。@ i n p u t的每个相邻行均被分隔开来,并在@ w o r d s中进行累加。