文章详情

  • 游戏榜单
  • 软件榜单
关闭导航
热搜榜
热门下载
热门标签
php爱好者> php文档>perl 读书笔记

perl 读书笔记

时间:2010-09-19  来源:h_xin8211

####################
#
#       声明
#
####################

此文是学习Perl过程的笔记,当做小手册使用,方便查找。此文档更新至 2010.01.01


此文语法点及例程出处:

Perl语言入门(第五版)  小骆驼

Perl语言编程(第三版)  大骆驼






第三章 列表与数组

$fred[0]="yabba"
qw简写        qw(...)

pop 取出数组中最后一个元素
$fred = pop(@array)
pop @array

push 添加一个(或一串)元素到数组尾端
push(@array,0)

shift 取出数组中第一个元素
$m=shift(@array)

unshift 添加一个(或一串)元素到数组开始处
unshift(@array,5)

foreach 控制结构
foreach $rock (qw/ a b c /){
        print "$rock";
}

reverse 按相反次序返回列表
@barney = reverse(@fred)

sort 根据ASCII码序排列
@sorted = sort(@rocks)


第四章 子程序
$_        老地方
@_        数组变量,存放子程序参数的数组,子程序专有变量
$n = &max(10,15); #此子程序有2 个参数

sub 定义子程序
&marine        调用子程序

use strict        严格规则的编译命令

return                从子程序中立即返回

4.5 私有变量
my                定义私有变量某个值

state                定义持久性私有变量

第五章 输入与输出
<STDIN>        读取标准输入
while(<STDIN>)        存储到变量里,每次读入一行
foreach(<STDIN>)        存储到数组里,每次读入所有文件

<>                读入程序后面的参数列表
@ARGV                <>的输入参数列表
                $_的值,从@ARGV中获得        
./my_program fred - betty        "-"表示从标准输入中获得

printf格式化输出
%d        十进制整数,舍去小数点之后的数字
%s        字符串,可设定宽度
        printf "%10s\n","wilma"        右对齐
        printf "%-15s\n","wilma"        左对齐
%f        转换浮点数,四舍五入,可指定小数点之后的输出位数
        printf "%12f\n", 23;
        printf "%12.3f\n",23;
        printf "%12.0f\n",23;

5.6 句柄
perl自身有六个句柄:STDIN STDOUT STDERR DATA ARGV ARGVOUT

Larry推荐句柄全部大写

5.7
open        定义其它的文件jubing
open CONFIG, “dino”;        # 打开一个CONFIG句柄,指向dino文件,从文件dino中读取数据。
open CONFIG, “<dino”;        # 同上,指定了方向。
open BEDROCK, “>fred”;
open LOG,“>>logfile”;

open CONFIG, "<", "dino";        # 同上,指定了方向。
open BEDROCK, ">", "fred";
open LOG, ">>", "logfile";

select        BEDROCK        选择文件句柄

close 关闭句柄
die函数将打印出你给它的消息
$!        仅对系统请求失败时,输出原因

say        输出变量值或字符串,并在后面自动加上换行符"\n"

第六章 哈希

$hash{$some_key}
%family_name                整个哈希

my &last_name = (
        "fred" => "flintstone",
        "dino" => undef,
        "barney" => "rubble",
);

keys函数        返回键列表
values函数        返回值列表
如在标量上下文中,这两个函数都会返回哈希中 键/值对的个数
my $count = keys %hash        # 得到 3

each函数        列出每个键/值对

exists函数        检查哈希中是否有某个键
if (exists $books{"dino"}){
        print "Hey,there's a library card for dino!\n";
}

delete函数        从哈希表中删除指定的键及其相对应的值

第七章 正规表达式


/(.)\1/        模式分组 反向引用
/((.)(.)\3\2)\1/        分组按左边括号顺序来划分
在perl5.10中,添加反向引用格式\g{1}
/(.)\g{1}/

7.2
/abba/                =         m!abba!

7.2.1
.        一次字符
.*        n个字符
(|)

7.2.2 量词
*        {0,}        
+        {1,}
?        {0,1}

7.3.1 字符类的简写
\d        数字                [0-9]
\w        "word"                [a-zA-Z0-9_]
\s         空白                [\f\t\n\r]

匹配完整单词 加“+”字符
\w+

perl5.10中增加简写
\h        匹配横向空白        [\t ]
\v        匹配纵向空格        [\f\n\r]
\R        匹配任何类型的断行

反义简写
[^\d]                \D        非数字
[^\w]                \W        非word
[^\s]                \S        非空白

第八章 正规表达式的应用

8.1
/.../是m/.../模式匹配的简写
/abba/         m/abba/        # 分隔符可选
(abba)
!abba!

8.2 可选修饰符
/i        不区分大小写
/s        匹配任何字符,增加换行符"\n"
/x        模式里随意添加空格,以使更容易阅读

8.3 锚定
^        开头匹配
$        结尾匹配
\b        词界锚定

8.4 绑定操作符 =~
$some_other=~/\brub/

8.6 捕获变量
$_ = “Hello there, neighbor”;
if(/(\S+) (\S+), (\S+)/){
print “words were $1 $2 $3”;
}

不捕获模式(?:...) 告知perl这一对括号完全是为了分组而存在的
if(/(?:bronto)?saurus (steak|burger)/){
        print "Fred wants a $1\n";
}

标签命名捕捉
(?<LABEL>PATTERN)        引用时用$+{LABEL}

反向引用也有新标识格式
\g{LABEL}

\k<LABEL>


8.6.2 自动匹配变量
%&        匹配部分
$`        匹配前部分
$'        匹配后部分
使用自动匹配变量,会使运行速度变慢,慎用

通用量词
a{3,15}
*        {0,}
+        {1,}
?        {0,1}

8.8 优先级
1.        ()
2.        数量词 * + ?{1,9}
3.        锚定和序列
4.        (|)
5.        元素 a [abc] \d \1

第九章 使用正规表达式处理文件

9.1
s///g                        全局查询并替换

s#^https://#http://#;        分隔符可改
s{fred}{barney};        
s[fred](barney);
s<fred>#barney#;

9.1.3 修饰符
/i        不区分大小写
/s        匹配任何字符
/x        添加空格

9.1.4 绑定操作
$file_name =~ s#^.*###s; #将$file_name 中所有的Unix 类型的路径去掉

9.1.5 大小写转换
\U                转换后均为大写
\L                转换后均为小写
\E                不影响后续字符
s/ (\w+) with (\w+) /\U$2\E with $1/i;
\u                变大写,但只影响之后的第一个字符
\l                变小写,但只影响之后的第一个字符
s/(fred|barney)/\u$1/gi;


也可在双引号中使用

9.2 split 定义分隔符
它会根据分隔符才开一个字符串,只要你能将分隔符写成模式的正规表达式
格式:@fields = split /separator/, $string;
默认,开头的空元素会被返回,结尾的空元素被丢弃,-l参数可保留
默认,会以空白字符为分隔符,对$_进行分割
my @fields = split; 等效于 split /\s+/,$_;

9.3 join函数
join与split恰好相反,join会把这些片段联合成一个字符串
注意:join 的第一个参数是字符串,而非模式
用法:my $result = join $glue,@pieces;
my $x = join ":",4,6,8,10,12; 结果$x为“4:6:8:10:12”

列表上下文中的m//
在列表上下文中使用模式匹配符(m//)时,如果模式匹配成功,那么返回的是所有捕获变量的列表;如果匹配失败,则会返回空列表。
my($first,$second,$thind) = /(\S+) (\S+), (\S=)/;
匹配中有一对圆括号的模式,它会在每次匹配成功时返回一个捕获串
my @words = ($text =~ /([a-z]+)/ig)
在哈希上下文中
my %last_name = ($date =~ /(\w+)\s+(\w+)/g);



9.5.1 非贪婪的数量词
.+?        从头进行非贪婪匹配
.*?
{5,8}?
{8,}?
??

9.5.2 匹配多行文本
/m
锚定符由原来的整个文本范围,变为整行范围

9.5.3 更新大量文件
先打开一个新文件,然后把跟就文件相同的内容写进去,并且在需要的位置进行改写
#! /usr/bin/perl –w
use strict;
chomp(my $date = ‘date’);
$^I =“.bak”;
while(<>){
s/^Author:.*/Author: Randal L. Scharwartz/;
s/^Phone:.*\n//;
s/^Date:.*/Date: $date/;
print;
}

9.5.4 在命令行中进行修改
$perl –p –i.bak –w –e ‘s/Randall/Randal/g’fred*.dat
-0<数字>
    (用8进制表示)指定记录分隔符($/变量),默认为换行
-00
    段落模式,即以连续换行为分隔符
-0777
    禁用分隔符,即将整个文件作为一个记录
-a
    自动分隔模式,用空格分隔$_并保存到@F中。相当于@F = split ”。分隔符可以使用-F参数指定
-F
    指定-a的分隔符,可以使用正则表达式
-e
    执行指定的脚本。
-i<扩展名>
    原地替换文件,并将旧文件用指定的扩展名备份。不指定扩展名则不备份。
-l
    对输入内容自动chomp,对输出内容自动添加换行
-n
    自动循环,相当于 while(<>) { 脚本; }
-p
    自动循环+自动输出,相当于 while(<>) { 脚本; print; }

9.5.5 非捕捉用的括号
if(/(?:bronto)?saurus (steak|burger)/)
{
        print “Fred wants a $1\n”;
}

第十章 更多控制结构

10.1 unless        
# 条件为假时 执行
# 或用 ! 取反
if(! ($fred =~ /^[A-Z_]\w*$/i)){
print “The value of \$fred doesn’t look like a Perl identifier name.\n”;
}

10.2 until
# 直到条件为真时,停止。
# while的取反

10.3 条件修饰词
# 只有单个表达式,才允许这样写。
print “$n is a negative number.\n”if $n<0;

10.4 裸块控制结构
# 没有关键字或条件的块
# 因临时变量声明在最小范围里,放在裸块中,限制my 临时变量的作用范围
#不循环,只执行一次,是一个伪循环
{
print “Please enter a number:”;
chomp(my $n = <STDIN>);
my $root = sqrt $n; #计算平方根                
print “The square root of $n is $root.\n”;
}

10.5 elsif
if(!defined $dino){
print “The value is undef.\n”;
}elsif($dino =~ /^-?\d+\.?$/){
print “The value is an integer.\n”;
}elsif($dino =~ /^-?\d*\.\d+$/){
print “The value is a _simple_ floating-point number.\n”;
}elsif($dino eq‘’){
print “The value is the empty string.\n”;
}else{
print “The value si the string ‘$dino’.\n”;
}



10.8 循环控制
last        立即结束
next        跳到下一循环
redo        回到此循环头部 在执行此循环

10.9
&&        # 逻辑与 AND
||        # 逻辑或 OR

10.9.2 三元操作符 ?:
# 第一个表达式为真时,执行第二个表达式,为假时,执行第三个表达式。
Express ? if_true_expr : if_false_expr

my $size =
        ($width < 10)? "small" :
        ($width < 20)? "medium":
        ($width < 30)? "large" :
                         "extra-large";

perl5.010中的 "否定义" 操作符 "//"
use 5.010;
my $last_name = $last_name{$someone} // '(No last name)';

模块
perldoc CGI        查询模块

perl Makefile.PL        手动安装模块到系统目录
make install

perl Makefile.PL PREFIX=/Users/fred/lib        手动安装模块到指定的目录

perl Build.PL                用辅助模块 Module::Build来编译并安装
./Build install        

有些模块有依赖关系,所以可以用自带的CPAN.pm来网络安装模块
perl -MCPAN -e shell

用cpan工具来网络安装模块
cpan Module::CoreList LWP CGI::Prototype

File::Basename模块
use File::Basename;

可选用模块中的部分函数列表
use File::Basename qw/basename/;

也可指定空函数列表
usr File::Basename qw//;
使用函数的模块全名来使用函数
my $dirname  = File::Basename::dirname $name


文件测试

检测选项含义
-r         文件或目录对此(有效的)用户(effective user)或组是可读的
-w         文件或目录对此(有效的)用户或组是可写的
-x         文件或目录对此(有效的)用户或组是可执行的
-o         文件或目录由本(有效的)用户所有
-R         文件或目录对此用户(real user)或组是可读的
-W         文件或目录对此用户或组是可写的
-X         文件或目录对此用户或组是可执行的
-O         文件或目录由本用户所有
-e         文件或目录名存在
-z         文件存在,大小为0(目录恒为false)
-s         文件或目录存在,大小大于0(值为文件的大小,单位:字节)
-f         为普通文本
-d         为目录
-l         为符号链接
-S         为socket
-p         为管道(Entry is a named pipe(a“fifo”))
-b         为block-special 文件(如挂载磁盘)        
-c         为character-special 文件(如I/O 设备)
-u         setuid 的文件或目录
-g         setgid 的文件或目录
-k         File or directory has the sticky bit set
-t         文件句柄为TTY(系统函数isatty()的返回结果;不能对文件名使用这个测试)
-T         文件有些像“文本”文件
-B         文件有些像“二进制”文件
-M         修改的时间(单位:天)
-A         访问的时间(单位:天)
-C         索引节点修改时间(单位:天)

同一文件的多项属性测试
if(-r $file and -w $file){
        ...}

因要翻阅所有文件两次,非常耗资源,所以使用虚拟文件句柄"_" 它会公诉用上次查询或的文件信息来做当前的测试
if(-r $file and -w -){
        ...}

stat 和 lstat 函数
返回属性信息,包括文件连接数,拥有者ID,之类的13个数字元素列表。

localtime 函数

第十二章 目录操作

chdir "/etc"

12.2 globbing 文件名通配

echo "*.pm"        -> shell
glob "*.pm"        -> perl
glob "*"        -> perl 不包括“.”
glob ".* *"        -> perl 由点开头文件 和 不由点开头的所有文件

my @all_files=<*>        # 同 @all_files=glob"*"

readline        # 得到间接文件句柄读入操作

12.4 目录句柄
从目录里取得文件名列表,返回所有文件,包括"." ".." 等隐含文件
next if $name =~ /^\./;        排除以点号开头的字符串
next if $name eq "." or $name eq "..";        排除当前目录和上级目录
opendir        # 打开目录句柄
readdir        # 读入目录中文件名
closedir        # 关闭目录句柄

12.7 删除文件 unlink
unlink返回删除的文件个数
unlink不能删除目录
rm        -> shell        # rm *.o
unlink        -> perl        # unlink glob "*.o" 返回删除文件个数
rmdir                        # 删除目录

readlink        取得符号链接指向的位置
my $where = readlink "carroll";
my $perl = readlink "/usr/local/bin/perl";

重命名文件 rename
rename "old", "new";

12.9 连接和文件
link                # ln 硬连接
symlink        # ln -s 软连接
readlink "carroll"        # 得到软连接的实体

12.10 创建和删除目录
mkdir "fred",0755                # 创建目录
rmdir "fred";                        # 只能删除空目录,不能递归删除目录,需要File:Path模块的rmtree函数

my $temp_dir = "/tmp/scratch_$$";                # $$ 当前进程号
mkdir $temp_dir,0700 or die "cannot create $temp_dir:$!";
...
unlink glob "$temp_dir/* $temp_dir/.*";        #删除临时目录下的所有文件,包括隐含文件
rmdir $temp_dir        


oct(0755)        # 十进制转为八进制



12.11 改变权限
chmod 0755,"fred","barney"        # 权限值为八进制

12.12 改变所有者
chown 1004,100,glob "*.o" # chown useID,groupID,filename
如不是ID指定,用名称指定属性
getpwnam函数        # 将用户名翻译成数字
getgrnam函数        # 将组名翻译成数字


12.13 改变时间戳 uptime
格式:utime 访问时间,修改时间,文件名
my $now = time;
my $ago = $now - 24*60*60
utime $now,$ago,glob"*"

第十三章 字符串和排序

13.1使用索引寻找子串
用法:$where = index($big,$small);                # 在$big字符串里寻找$small字符串首次出现的地方那个
                                                # 开头找到返回0,无法找到返回-1
用第三个参数来制定开始搜索的地方
my $stuff = "Howdy world!";                
my #where1 = index($stuff, "w");                        # $where1为 2
my #where2 = index($stuff, "w", $where1+1);        # $where2为 6
my #where3 = index($stuff, "w", $where2+1);        # $where3为 -1 (没找到)

rindex        搜索子串最后出现的位置
my $stuff = "Howdy world!";                
my #where1 = rindex($stuff, "w");                        # $where1为 5
my #where2 = rindex($stuff, "w", $where1+1);        # $where2为 8
my #where3 = rindex($stuff, "w", $where2+1);        # $where3为 -1 (没找到)

13.2 substr
substr($string,开始字符数,截取长度)
substr($string,开始字符数)                # 开始到截止
substr($string,-3,2)                        # 从倒数第三个字符开始

index与substr协同工作
my $long = "some very very log string";
my $right = substr($long, index($long, "l"));        # 取出以字符l的位置开头的子串

my $string = "Hello, word!";
substr($string,0,5) = "Goodbye";        # $string现在为 "Goodbye,world!"

substr($string, -20)=~ s/fred/barney/g;        # 只会处理最后20个字符的匹配替换

substr 第四个参数,替换子串串
my $previous_value = substr($string, 0, 5, "Goodbye");  # 现在为 "Goodbye,world!"

用sprintf格式化数据
sprintf格式化后的字符存储在变量里

my $date_tay = sprintf
        "%4d/%02d/%02d %2d:%02d:%02d",
        $yr, $mo, $da, $h, $m, $s;                # 2009/01/19 3:00:08

my $money = sprintf "%.2f", 2.49997;        # 四舍五入 得到 2.5

逗号分隔数字,以便读取
sub big_money {
        my $number = sprintf "%.2f", shift @_;
        1 while $number =~ s/^(-?\d+)(\d\d\d)/$1,$2/;
        $number =~ s/^(-?)/$1\$/;
        $number;
}

13.4 高级排序

飞碟操作符
<=>        #  数字的三向比较
cmp        #  字符串的三向比较
$a <=> $b        # 如$a在$b之前,返回-1 如$b在$a之前,返回1 如相等,返回0

内嵌的排序子程序
sub by_number{$a<=>$b}
my @numbers = sort {$a<=>$b} @some_numbers;                        # in line子程序
my @numbers = reverse sort {$a<=>$b} @some_numbers;                # 反向,降序排列

my @numbers = sort {$b<=>$a} @some_numbers;                        # 反向,降序排列

哈希按值排序
sub by_score = {$score{$b} <=> $score{$a}};        # 按哈希值的降序排列,所以是 $b <=> $a


第十五章 智能匹配与given-when结构 (perl5.10中出现)

新的智能匹配操作符(~~)
1. 如果操作数看起来是数字,就按数字来比较大小。
2. 如果操作时看起来时字符串,就按字符串来比较。
3. 如某一段操作数是正规表达式,就当作模式匹配来执行。
4. 如果是数组,就一个个匹配数字里的值。

%a ~~ %b                # 哈希的键是否一致
%a ~~ @b                # 至少%a中的一个键在列表@b之中
%a ~~ /Fred/                # 至少一个键匹配给定的模式
$a ~~ 'Fred'                # 哈希中某一指定键$a{Fred}是否存在

@a ~~ @b                # 数组是否相同
@a ~~ /Fred/                # 有一个元素匹配给定的模式
@a ~~ 123                # 至少有一个元素转化为数字后是123
@a ~~ 'Fred'                # 至少有一个元素转化字符串后是'Fred'

$name ~~ undef        # $name确实尚未定义
$name ~~ /Fred/        # 模式匹配
123 ~~ '123.0'        # 数字和字符串是否大小相等
'Fred'~~ 'Fred'        # 字符串是否完全相等
123 ~~ 456                # 是否大小相等

1. 字符串
use 5.0.10;
print "I found Fred in the name!" if $name ~~ /Fred/;

2. 哈希键值
use 5.0.10;
print "I found a key matching 'Fred'" if %name ~~ /Fred/;

3. 数组
use 5.0.10;
print "The arrays have the same elements!"
        if @names1 ~~ @names2;

given-when 控制语句

同 if-elsif-else 相仿,区别是given-when可以再满足某个条件的基础上,继续测试其他条件

use 5.0.10;
given( $ARGV[0]){
        when( /fred/i ){say 'Name has fred in it'}
        when( /^Fred/ ){say 'Name starts with Fred'}
        when( 'Fred'){say 'Name is Fred'}
        default        {say "I don't see a Fred"}
}

多个项目的when匹配

use 5.0.10;
foreach my $name ( $names){
        when( /fred/i ){say 'Name has fred in it'}
        when( /^Fred/ ){say 'Name starts with Fred'}
        when( 'Fred'){say 'Name is Fred'}
        default        {say "I don't see a Fred"}
}

第十六章 进程管理

system函数
启动子进程最简单的方法是用system函数,例如要从perl调用unix的date命令,用 system "date";
这会创建一个字进程来运行date命令

system 'ls -l $HOME';

system "ls -l \$HOME";

逻辑真假判断:
unix里:        0-真        非0-假
perl里:        0-假        非0-真

所以,在system里要先颠倒真假
unless (system 'date'){
        # 返回 0 的话就代表执行成功,往下执行
        print "we gave you a date, OK!\n";
}

最简单做法就是在system操作符之前加上逻辑反,感叹号"!"
!system "rm -fr files_to_delete" or die "something went wrong";

exec函数
同system函数相仿
exech函数导致perl进程自己去执行任务

环境变量
perl的环境变量存储在特殊的哈希 %ENV 中
%ENV会先从shell中继承环境变量
后续也可以修改

$ENV{'PATH'} = "/home/rootbeer/bin:$ENV{'PATH'}";
delete $ENV{'IFS'};
my $make_result = system "make";

用反引号捕获输出结果
my $now = `date`;                        # 捕获date输出
print "The time is now $now";        # 不需要换行符\n 因为date的输出已经包含了
如要去除\n, 用chown
chown(my $now = `date`;)

在列表上下文中使用反引号
my @who_lines = `who`        # 可完整保存输出的格式

my $who_text = `who`                # 输出保存在一个标量文本里




相关阅读 更多 +
排行榜 更多 +
毒药轮盘手机版下载

毒药轮盘手机版下载

休闲益智 下载
剑侠情缘零b服手游下载

剑侠情缘零b服手游下载

角色扮演 下载
惊魂动物园游戏手机版下载

惊魂动物园游戏手机版下载

冒险解谜 下载