第一章 简介
CPAN就是perl综合典藏网(Comprehensive Perl Archive Network),
网址:http://search.cpan.org/
$ chmod a+x my_program ###将程序文件的属性修改为可执行。
第二章 标量数据
标量=数字or字符
数字包括浮点数直接量、整数直接量、非十进制的整数直接量、数字操作符(取模操作符:% 表达式10%3的结果是1,也就是10除以3的余数,2**3代表2的3次方)。
字符串:就是一个字符序列。(如果想在源代码中使用Unicode书写直接量的话,得手工加上utf8编译指令。=use utf8)
单引号内的字符串直接量:指的是一对单引号(')圈引的一串字符。单引号内所有的字符都代表它们自己,要表示反斜线字符本身,需要在这个反斜线字符前面再加一个反斜线字符表示转义,要表示单引号本身时,同样在单引号前面加一个反斜线字符表示转义)例如:'hello\n' #hello后面接着反斜线和字母n。
双引号内的字符串直接量:"hello world\n" #hello world,后面接着换行符。
"coke\tsprite" #coke、制表符(tab)和sprite。因此,要通过反斜线转义表示换行符(\n)那样的特殊字符的话,就该用双引号书写直接量。
\n #换行
\r #回车
\t #水平制表符
\f #换页符
\b #退格
\e #Esc(ASCII编码的转义字符)
字符串操作符:字符串可以用.操作符连接起来。
例如:"hello" . "world" #等同于"helloworld"
"hello" . ' ' . "world" #等同于"hello world"
x表示字符串重复操作符,例如:"fred" x 3 #得"fredfredfred"
数字和字符串之间的自动转换,
例如:"Z" . 5*7 #等同于"Z" . 35,得到"Z35"。
标量变量:存储的是单个标量值。标量变量的名称以$开头,(区分大小写)
例如:$fred = 17; #将$fred的值设为17
$barney = 'hello'; #将$barney的值设为'hello'
$barney = $fred+3; #将$barney设为$fred当前值加上3的结果,即20
$barney = $barney*2;# $barney被设为$barney当前值乘2的结果, 即40
双目赋值操作符:$fred = $fred + 5; #不使用双目赋值操作符
$fred += 5; #使用双目赋值操作符
$barney = $barney * 3;等同于 $barney *= 3;
$str = $str. " "; #在$str末尾追加一个空格字符
$str .= " "; #用追加操作符做同样的事
$fred **= 3; #将$fred里面的值自乘3次,再存回$fred
字符串中的标量变量内插:$meal = "brontosaurus steak";
$barney = "fred ate a $meal"; #$barney="fred ate a brontosaurus steak"
$barney = 'fred ate a ' .$meal; #另一种等效上面的写法
例如:$fred = 'hello';
print "The name is \$fred.\n";
## 输出是The name is $fred.
##########################
$what = "brontosaurus steak";
$n = 3;
print "fred ate $n $whats.\n";
print "fred ate $n ${what}s.\n";
print "fred ate $n $what" . "s.\n";
结果是:fred ate 3 .
fred ate 3 brontosaurus steaks.
fred ate 3 brontosaurus steaks.
借助代码点创建字符:直接键入这些字符的代码点,再通过chr()函数转换成对应的字符。例如:$alef = chr( oxo5Do );
通过ord()函数把字符转换成代码点:$code_point=ord('? ');
比较操作符: 比较 数字 字符串
相等 == eq
不等 != ne
小于 < lt
大于 > gt
小于或等于 <= le
大于或等于 >= ge
!表示单目取反操作符。
if (! $is_bigger) {
# 如果$is_bigger不为真,则执行这里的代码
}
chomp操作符:例如: chomp($text = <STDIN>);#读入文字,略过最后换行符。
$text = <STDIN>;
chomp($text);#做同样的事,分两步
undef值:undef既不是数字也不是字符串,它完全是另一种类型的标量值。
defined函数:判断某个字符串是undef而不是空字符串,可以用defined函数。如果是undef,该函数返回假,否则返回真。
第三章 列表与数组
列表(list)指的是标量的有序集合。
数组(array)则是存储列表的变量。
列表指的是数据,而数组指的是变量。
最后一个元素的索引值是$#rocks.但是这个数字比数组元素的个数少1,因为还有一个编号为0的元素。
$end = $#rocks; ##99,也是最后一个元素的索引值
$number_of_rocks = $end + 1;
$rochs[ $#rocks ] = 'hard rock';##最后一块石头
$rocks[ -1 ] = 'hard rock';##同上
..范围操作符:(1..100);##1到100构成的整数
qw简写:qw/ fred barney betty wilma dino /
等同于 ("fred", "barney", "betty", "wilma", "dino")
但是qw构建的列表中,不能像双引号内的字符串一样使用\n或$fred。
($wilma, $dino) = qw/ flintstone /; ##$dino的值为undef。
@rochs = qw/ bedrock slate lava /;##@rochs可以读作"所有的rocks"。
pop操作符,它负责取出数组中最好一个元素(或一串元素)并将其作为返回值返回,
@array = 5..9;
$fred = pop(@array); # $fred变成9,@array 现在是(5, 6, 7, 8)
push操作符:用于添加一个元素到数组的尾端。
@array = 5..9;
push(@array,0); # @array现在是(5..9, 0)
@others = qw/ 9 0 2 1 0/;
push @array, @others; # @array又得到了5个新元素
shift和unshift操作符:针对数组的最左端进行处理。
shift等同于pop,unshift等同于push。
splice操作符:针对数组中间元素,最多接受四个参数,最后两个是可选参数。第一个参数是要操作的目标数组,第二个参数是要操作的一组元素的开始位置。
@array = qw/ pebbles dino fred barney betty /;
@removed = splice @array, 2;# 在原来的数组中删除fred及其后的元素
# @removed变成qw/ fred barney betty /
# 而@array则变成qw/ pebbles dino/
通过第三个参数可以指定要操作的元素长度。
@array = qw/ pebbles dino fred barney betty /;
@removed = splice @array, 1, 2; # 删除dino和fred这两个元素
# @removed变成qw/ dino fred /
# 而@array变成qw/ pebbles barney betty /
第四个参数是要替换的列表。
@array = qw/ pebbles dino fred barney betty /;
@removed = splice @array, 1, 2, qw/wilma/; # 删除dino和fred
# @removed变成qw/dino fred/
# @array变成qw/ pebbles wilma dino fred barney betty /
foreach控制结构:foreach(循环)能逐项遍历列表中的值,依次迭代。
foreach $rock (qw/ bedrock slate lava /) {
print "One rock is $rock.\n" #依次打印所有的三种石头的名称
};
Perl中最喜欢用的默认变量:$_
foreach (1..10) { # 默认会用$_作为控制变量
print "I can count to $_!\n";
};
reverse操作符:reverse操作符会读取列表的值(也可能来自数组),并按照相反的次序返回该列表。
@fred = 6..10;
@barney = reverse(@fred); #得到10,9,8,7,6
sort操作符:排序用的。
each操作符:提取哈希的键和值。
use perl;
my @rocks = qw/ bedroch slate rubble granite /;
while( my( $index, $value ) = each @rocks ) {
say "$index: $value";
};
不用each来实现,
@rocks = qw/ bedroch slate rubble granite /;
foreach $index ( 0.. $#rochs ) {
print "$index: $rocks[$index]\n";
};
在列表上下文中使用产生标量的表达式:
@wilma = undef; #结果是一个列表,而且仅有一个元素为未定义的(undef)
@betty = ( ); # 这才是正确的清空数组的方法。
强制指定标量上下文:可以使用伪函数scalar。它不是真正的函数,只是告诉perl这里要切换到标量上下文,
@rocks = qw/ talc quartz jade obsidian /;
print "How many rocks do you have?\n";
print "I have ", @rocks, " rocks!\n"; #错误,这会输出各种石头的名称
print "I have ", scalar @rocks, " rocks!\n"; # 这会输出石头的种数
第四章 子程序
定义子程序:可使用关键字sub、子程序名(不包含与号)以及用花括号封闭起来的代码块,这部分代码就是子程序的主体。
第五章 输入与输出
来自钻石操作符的输入:使用钻石操作符<>,它能让程序在处理调用参数时,提供类似于标准Unix工具程序的功能。
文件句柄(filehandle):就是程序里代表Perl进程与外界之间的I/O联系的名称。
Perl中6个特殊的文件句柄:STDIN、STDOUT、STDERR、DATA、ARGV、ARGVOUT
打开文件句柄:
open CONFIG, 'dino'; # 读取文件dino,而非写入。
open CONFIG, '<dino'; # 读取文件dino,而非写入。
open BEDROCK, '>fred'; # 打开文件句柄并输入到新文件fred中。
open LOG, '>>logfile'; # 追加的方式打开文件。
第六章 哈希
哈希是一种数据结构,它和数组的相似之处在于可以容纳任意多的值并能按需取用,而它和数组的不同在于索引方式,数组是以数字来索引,哈希则以名字来索引。也 就是说,哈希的索引值,此处称为键(key),并不是数字,而是任意唯一的字符串。
哈希是从键到值的单行道,我们无法在哈希中查询值并反推出其相应的键。
访问哈希元素:$hash{$some_key};表示索引值(哈希键)。并且键表达式是字符串,而不是数字。
$family_name{'fred'} = 'flintstone';
$family_name{'barney'} = 'rubble';
访问整个哈希:%some_hash = ('foo', 35, 'bar', 12.4, 2.5, 'hello', 'wilma', 1.72e30, 'betty', "bye\n");
在列表上下文中,哈希的值是简单的键-值对列表:
@any_array = %some_hash;
我们称呼这个变换为展开哈希,将它变成键-值对列表。当然,得到的键-值对不一定是按照当初的赋值时的顺序展开的。
print "@any_array\n";#可能出现下面结果:betty bye\n wilma 1.72e+30 foo 35 2.5 hello bar 12.4 ;
哈希赋值:my %new_hash = %old_hash;
胖箭头:对应哈希中的逗号。使用胖箭头可以省略键的引号。键会被自动引起。
my %last_name = ( # 哈希也可以是词法变量
fred => 'flintstone',
dino => undef,
barney => 'rubble',
betty => 'rubble',
);
keys和values函数:keys函数能返回哈希的键列表,而values函数能返回对应的值列表。
my %hash = ('a' => 1, 'b' => 2, 'c' => 3);
my @k = keys %hash;#@k包含'a'、'b'和'c';
my @v = values %hash; #@v包含1、2和3;
my $count = keys %hash; #得到3,也就是说有三对键值。
each函数:需要迭代(逐项处理其中的每一个元素)整个哈希。
实际使用时,唯一适合使用each的地方就是在while循环中,如下所示:
while ( ($key, $value) = each %hash ) {
print "$key => $value\n";
}; #each%hash会从哈希返回一组键-值对,结果是含有两个元素的列表:如果键是"c"而值是3,则列表就会是("c", 3)。
exists函数:检查哈希中是否存在某个键。
delete函数:能从哈希中删除指定的键及其相对应的值。
my $person = "betty";
delete $books{$person}; #删除$books{$person};
哈希元素内插:可以将单一的哈希元素内插到双引号引起的字符串中。
第七章 漫游正则表达式王国
Unicode属性:Unicode字符能够理解自身含义,它们不只是简单的字节序列。每个字符除了字节组合之外,还附带着属性信息。所以除了匹配字符本身以外,我们还能根据字符的属性来达成匹配。
若要匹配某项属性,只需要把属性名放入\p{PROPERTY}里面。空白符:\p{Space};
若要匹配不包含特定属性的字符,只要把小写的p改成大写,就表示否定意义,匹配指定属性以外的字符。
关于元字符:点号(.) 是能匹配任意一个字符的通配符,当然换行符(\n)要除外。
但是在任何元字符前面加上反斜线,就会使它失去元字符的特殊作用。
*表示无限多次
+表示前一个条目至少一次。
?表示前面一个条目是可有可无的。如:/bamm-?bamm/只会匹配bamm-bamm或者bammbamm;
模式分组:(.)\1表示需要匹配连续出现的两个同样的字符。
如:$_ = "abba";
if (/(.)\1/) { # 匹配 'bb'
print "It matched same character next to itself!\n";
}
从Perl 5.10开始用\g{N}这种形式,其中N是想要反向引用的组号。
如:use 5.010;
$_ = "aaa11bb";
if (/(.)\g{1}11/) {
print "It matched!\n";
}
择一匹配:竖线(|)通常可以读或,意思是要么匹配左边的内容,要么匹配右边的内容。
字符集:指的是一组可能出现的字符,通过写在方括号([])内表示。它只匹配单个字符,但可以是字符集中列出的任何一个。
字符集的简写:表示任意一个数字的字符集的简写是\d;
\s简写能匹配任意空白符,效果上等同于Unicode属性\p{Space};
\h只匹配水平空白符,\v则只匹配垂直空白符。把\h和\v并起来,就是\p{Space};
/a表示需要严格按照ASCII的范围来匹配数字字符时,将其写在正则表达式末尾。
\R简写能匹配任意一种断行符。
\w:在ASCII语义下,其匹配的是这样一组字符:[a-z A-Z 0-9];
反义简写:[\d\D]表示任何数字和非数字。它会匹配任意字符,包括换行符。
而点号则只能匹配换行符以外的所有字符。
[^\d\D]匹配既不是数字也不是非数字的字符,它什么都不匹配。
第八章 用正则表达式进行匹配
用m//进行匹配
我们之前用双斜线的写法表示模式,比如/fred/,但是事实上,这是m//的简写。
应当选择模式中不会出现的字符作为定界符。
用/i进行大小写无关的匹配,
用/s匹配任意字符,点号(.)无法匹配换行符,
用/x加入空白符,
选择一种字符解释方式:
修饰符/a告诉perl采取ASCII方式,/u则表示采取Unicode方式,最后一种/l表示遵从本地化语言的设定,按照对应的字符集编码作相应的处理。
锚位:通过给定锚位,我们可以让模式仅在字符串指定的位置匹配。
\A锚位匹配字符串的绝对开头,不会顺移到下一个位置继续尝试。
\z会匹配字符串的绝对末尾。
\Z类似行末的锚位,它允许后面出现换行符。
^表示行首,$表示行末。
绑定操作符(=~):默认情况下模式匹配的操作对象是$_,绑定操作符告诉perl,拿右边的模式来匹配左边的字符串,而不是匹配$_ .
第九章 用正则表达式处理文本
用s///进行替换;
用/g进行全局替换;
split操作符:它会根据给定的模式拆分字符串。
my @fields = split /:/, "abc:def:g:h";
#得到("abc", "def", "g", "h")
join函数:它的功能与split恰好相反。