Perl : Practical Extraction and Report Languaue 实用报表提取语言
Perl被设计为:90%处理文本,10%针对其他情况
机器中的Perl通常被放在 /usr/bin/perl或/usr/local/bin/per中,如果不是这样,则需要找到你机器上perl存放的地点,在Unix系统中,可以用此语句找到perl
#! /usr/bin/env perl
大小写敏感
正则表达式
在Perl中常常叫做模式,是一个匹配某字符串的模版
标量定义时用$标示
数组定义时用@标示
Hash表 定义时用%标示
my $username="oracle";
my @tabels=("customer","order");
my %week=((1=>'monday'),(2=>''tuesday'));
任意一个标量变量可以赋值 整形、浮点型、字符串
数组变量的元素可以是不同的标量、也可以是数组、hash表
根据操作符的不同自动判断是数字还是字符串
x表示某字符串重复多少次 5x4 表示5555
n*=3 表示n=n*3
双引号内插
双引号内的标量变量,将被其值代替
用{}将变量名括起来
Perl程序员在使用新变量时,通常不初始化,从而将变量作为0或者空串使用。
列表中的每一个元素都是一个独立的标量值,这些值是有顺序的。
数组或列表中的元素是编了号的,其索引从整数0开始,因此数组或者列表第一个元素的索引为0
$fred[0]="yabba";
下标是任何能返回数值的表达式。如果其值不为整数,则自动将其转换为小于它的最大整数值
如果下标超出了数组的范围,则其值为undef
boolean:
如果值为数字,0是false;其余为真
如果值为字符串,则空串(‘’)为false,其余为真
如果值的类型既不是数字又不是字符串,则将其转换为数字或字符串后再利用上述规则
undef为false,所有的引用都是true
..范围操作符,只能从小到大
(1..5) #同(1,2,3,4,5)
(1.7..5.7) #同上,最小值和最大值被转换成整数
("fred","barney","betty","wilma","dino")
qw(fred barney betty wilma dino)#意思相同,但输入更少qw表示quoted words qw内不可添加注释
在数组名前加@来引用整个数组,@rocks可以读作all of the rocks
@quarry=(@tiny,$dino); #数组名字被其列表值替换,数组不能成为列表的一个元素,因为数组只能包含标量值,不能包含其他数组
pop将数组最后一个元素取出并返回
push可以将一个或一列元素加在数组末尾
pop push是对数组的末尾进行操作,shift和unshift是对数组的开头进行操作
$email="lala/@163.com";
$_ 默认变量
$#array 表示@array元素的索引
47页标量和列表上下文章节非常重要
数组在标量环境下使用,将返回其个数
可以使用&子程序的名字,来调用子程序
返回值为最后一个被计算的表达式
如果程序长度大于一个屏幕,推荐使用 use strict
<>读入输入,但输入内容本身被存储在$_
print @array;打印出元素的列表,一个接一个,无空格。如果字符串包含换行符,通常采用此形式
print"@array";打印出一个字符串(包含一个内插的数组)(每个元素之间用空格隔开)
文件句柄是Perl程序I/O连接的名字,是Perl和外界的纽带。也就是说它是连接的名字,而非文件的名字。推荐句柄所有字幕均大写
>>打开一个文件,数据追加到文件后面
哈希和数组类似,索引不是数字而是名字
hash是单向的,由key到value
哈希常用用法:此词出现的次数。
如果你的任务是关于:“查询重复的”,“唯一的”,“交叉引用的”,“查询表”,则hash很可能在这类应用中帮上你的忙
访问hash元素,可以使用下面的语法
$hash{$some_key} #注意使用花括号
hash元素的名字和key之间可以用for连接。如the family_name for fred is flintstone,因此hash 名为family_name
hash的key可以是任意的表达式
要引用整个hash,使用%作为前缀
hash的值(在列表context中)是一个key/value对的列表
@array_array=%some_hash; 我们把这称为:将hash展开,并将其key/value对返回到一个列表中。
%inverse_hash=reverse %any_hash; 将hash反转,将key 和value的值交换了
在Perl的语法中,在需要逗号,的时候,都可以使用大箭头=>符号替换,对于Perl来讲,它们是一样的。
my%last_name=("fred"=>"flintstone","dino"=>undef,); 很容易辨别出哪个是key,哪个是value
keys函数返回所有keys, values函数返回所有的values
my%hash=("a"=>1,"b"=>2,"c"=>3);
my @k=keys%hash;
my @v=values%hash;
each,一般只在while循环中使用each。将返回key/value对的2元素列表
exists,要查看hash中是否存在某个key,可以用exists函数,如果hash中存在此key,则返回true,这和是否有对应的value无关
delete函数将某个给定的key(包括其对应的value)从hash中删除
正则表达式,在Perl中通常被称为模式:某个模板是否匹配某个字符串。它只有一个任务:查找某个字符串,返回“匹配”或者“不匹配”。这就是它完成的所有工作。
要匹配某个模式(正则表达式)和$_的关系,可以将模式放在正斜线(//)之间
$_="yabba dabba doo";
if(/abba/){
print"It matched!/n";
}
表达式/abba/将在$_寻找这四个字母,如果找到,则返回true
由于模式匹配通常返回true或false,因此经常用在if或while的条件表达式部分
所有在双引号中的转义字符在模式中均有效,因此你可以用/coke/tsprite来匹配coke,tab(制表符),sprite
元字符 (.)点是通配符,匹配任何单个的字符,但不包括换行符/n。如果只希望匹配英文句号,可以使用反斜线。
1量词(*)星号表示匹配前一项0次或者多次。
2量词(+)可以匹配前面一项的一个或多个,至少一个 /fred +barney/不会匹配fredbarney,中间至少应该有一个空格
3量词(?)前面一个项出现一次,或者不出现,要么出现1次,要么出现0次,没有其他情况
这三个数量词必须紧跟在某些项的后面,因为它是指前面项重复的次数。
4一般的数量词,章节8.7
{5,15}表示前一项允许重复的次数。/a{5,15}/,匹配5个到15个a中的任意一个(包括5和15),如果出现3个则匹配不上,如果出现5个10个15个则能匹配上。
如果省略掉第二个数字,逗号留下,则没有上限了。
如果省略第二个数字和都好,将匹配确定的次数。
//w{8}/将严格的匹配8个word(字母数字下划线)/,{5}chameleon/将匹配,,,,,chmeleon
*等同于{0,}
+等同于{1,}
?等同于{0,1}
实际程序中很少使用花括号的数量词,*,+,?基本已经可以应付
5(+?)非贪婪的数量词(章节9.5.1),它将匹配一次或多次,但其匹配尽可能少的次数,而非尽可能多的次数。
(.*)点加星,任意字符串匹配模式
/(fred)+/能匹配上像fredfredfred这样的字符串
/(fred)*/能匹配上任何字符串,包括空串
|竖线,通常被读作or,意思是匹配左边或者右边的,如果竖线左边没有匹配上,则匹配右边。
字符类[abcwxyz]可以匹配上括号内七个字母中的任意一个,可以使用连字号(-)表示某个范围的字母,因此这个也可写作[a-cw-z]
字符类前使用^将取此字符类的补集[^n/-z]将匹配上n,-,z之外的任何字符
字符类简写:
[0-9] /d 补集[^/d] 或写作/D
字母,数字,下划线的单个字符(不能匹配单词) /w 补集[^/w]或写作/W
某个单词 /w+
空白(/f/t/n/r格式符,制表符,换行符,回车) /s 补集[^/s]或写作/S
m//匹配可以使用任何成对的分隔符,如果用//则可以省略m
比如匹配http://可以不用//进行匹配,如m%http://%,花括号也比较常用
要创建一个大小写无关的模式,可以使用修饰符/i。if(/yes/i)
匹配任何字符/s (包括换行符)
添加空格:/x (允许你在模式中加入任何数量的空白,增强模式的可读性)
/-?/d+/.?/d*/
/-? /d+ /.? /d*/x #加入空格后,更容易阅读
注释:-?可选的负号 /d+小数点前一个或多个十进制数字 /.?可选的小数点 /d*小数点后一些可选的十进制数字
/i /s /x可以结合使用,顺序无所谓 如 /is /six
锚定^只匹配字符串开头,$只匹配字符串结尾
/^fred/以fred开头的 /rock$/以rock结尾的
同时使用两个锚定确保匹配整个字符串/^fred$/
/^/s*$/将匹配一个空行
/b词锚定 //bfred/b/可以匹配单词fred
//bhunt/将匹配上像hunt,hunting,hunter这样的单词,但不会匹配shunt,而/stone/b/将匹配sandstone,而不能匹配上capstones.
(=~)8.4绑定操作符
对$_进行匹配只是默认的行为,使用绑定操作符=~将告诉Perl将右边的模式在左边的字符串上进行匹配,而非对$_匹配
8.6匹配变量,变量个数同模式中括号对数的个数是相同的。
$4指第四对括号所匹配的字符串。
自动匹配变量:$& , $` , $'
$& 整个被匹配的部分
$` 匹配部分的前一部分
$' 匹配部分的后一部分
如果将这三个变量放在一起,你将得到原始字符串
自动匹配变量会使正则表达式的运行速度变慢,许多程序员使用替代的方法,如果需要使用$&,那么在整个模式上加上括号,并使用$1代替。
第九章
s/// 查询并替换
m//可以和任何字符串表达式进行匹配,s///只能修改被称为左值(lvalue)的数据。这通常是一个变量,虽然它可以是任何可在赋值符左侧出现的东西。
$_="He's out bowling with Barney tonight";
s/Barney/Fred/; #Barney被Fred替换掉
print"$_/n";
s///只进行一次替换
/g 全局替换 修饰符要求将不相重叠的所有匹配上的部分都进行替换
全局替换一个常用地方是将多个空格用单个空格替换掉:
$_="input data/t may have extra whitespace.";
s//s+/ /g; #现在是“input data may have extra whitespace.”
/U 紧跟着的都是大写
/L 紧跟着的都是小写
9.5.4
$perl -p -i.bak -w -e 's/Randall/Randal/g' fred*.dat
-p要求perl为你写一个程序
while(<>){
print;
}
-n比-p自动省略掉print语句
-i.bak 在程序开始处将$^ I的值设置为“.bak”
-i 如果不需要备份文件,可以使用-i
-w将警告打开
-e 执行下面的代码。即是说s/Randall/Randa/g被当作perl代码执行,由于我们有while循环(-p选项),这段代码将被放在循环内),print之前。-e代码中最后一个分号是可以省略的。如果有多个-e选项,因此有多块代码,只有最后一个分号是可省略的。