前言

  • 在看这篇文章之前,推荐先看下《卧槽!perl和C语言实现对比,perl代码量太赞了!》,不知道你看了吗2?
  • 推荐一些文章:
  • Perl系列文章
  • 两个半小时学会Perl
  • Perl 教程
  • 本文内容是基于《Perl语言入门·第七版》整理所得,而且章节标题和书籍基本对应。
  • 本文食用方式,推荐使用搜索关键字查看目录的方式快速索引到需要的内容;
  • 本文内容全部是手敲的,难免有错误,望各位看客多多包涵!
  • 本文涉及到的习题,基本都实现了,并且同步在了Gitee,按需下载

第1章 简介

  • 《Perl语言入门·第七版》
  • https://www.learning-perl.com/可以下载源代码
  • https://www.cpan.org/是Perl综合典藏网,包含很多基于Perl的内容,如源代码、安装程序、示例文件

第2章 标量数据

  • scalar(标量)
  • 标量数据:表示数据的内容,就是值;
  • 标量变量:表示存储标量数据的容器;

数字

前置零的写法只用于表示数字直接量,不能用于字符串和数字间的自动转换。

字符串

养成加上use utf8;的习惯。

单引号内的字符直接量

  • 单引号字符串中,反斜线表示转义的两种情况:反斜线后面跟反斜线或单引号

双引号内的字符直接量

  • 与单引号相比,转义字符的内容更加强大。
组合 意义
\n 换行
\t 水平制表符
\r 回车
\f 换页符
\b 退格
\a 系统响铃
\e 跳出(ASCII编码的转义字符)
\\ 反斜线
\“ 双引号
\l 将下个字母转为小写
\L 将它后面的所有字符都转为小写,直到\E为止
\u 将下个字母转为大写
\U 将它后面的所有字符都转为大写,直到\E为止
\E 结束\L、\U和\Q开始的作用范围

字符串操作符

操作符可以使用句点符号.进行拼接!

Perl的内置警告信息

  • 形式1:
#!/usr/bin/perl
use warnings;
  • 形式2:
#!/usr/bin/perl -w
  • 形式3:
    运行时加上 -w选项!
  • use diagnostics;报告核心内容

标量变量(variable)

和其他语言一样,只是perl的变量需要拿钱买来,形如$fred

print输出结果

  • say代替print输出结果
perl -E 'say q(hello, world)'                                   [255]
hello, world

字符串中的标量变量内插

变量内插有时候又叫双引号内插

比较操作符

  • 注记:
  • lt:less than
  • gt:greater
  • eq:equal
比较 数字 字符串
相等 == eq
不等 != ne
大于 >= lt
小于 < gt
小于或等于 <= le
大于或等于 >= ge

if控制结构

  • 和其他语言一样

获取用户输入

$line = <STDIN>

chomp操作符

  • 取消末尾的换行符
  • chomp函数的返回值是移除的字符数
chomp($text = <STDIN>);#读取不带换行符的输入#等价于
$text = <STDIN>;
chomp($text);

while控制结构

  • 与其他语言一样

undef值

ubdef作为数字、字符串使用时会被视作数字零空字符串

defined函数

defined函数:判断某个字符串是否为空,如果是undef,返回假!

习题

第3章 列表与数组

访问数组中的元素

注意$fred[0]fred是两个不同的东西

特殊的数组索引

如果数组定义如下:

$name[0] = 'a';
······
$name[88] = 'asd';

最后一个元素的索引可以是$#name-1

列表直接量

(1, 2, 3) #包含三个数字的列表
(1,"fred", 2) #列表内元素存储格式灵活(1..100) #从1到100的整数序列

qw简写

  • qw表示为quoted word用引号引用的词或 quoted by whitespace用空白引用的词;
("fred", "barney", "betty", "wilma", "dino")# 等价的几种写法,少了很多引号,方便使用!
qw( fred barney betty wilma dino )
qw! fred barney betty wilma dino !
qw{ fred barney betty wilma dino }
qw[ fred barney betty wilma dino ]
qw/ fred barney betty wilma dino /
qw< fred barney betty wilma dino >
qw# fred barney betty wilma dino #
······

列表的赋值

pop和push操作符

  • 删除增加数组末尾元素

shift和unshift操作符

  • 删除增加数组开头元素

splice操作符

splice 最多接收4个参数,分别为目标数组操作数组的开始索引操作的元素个数替换的元素

字符串中的数组内插

  • 注意在使用@符号的时候,在输入邮箱的时候,需要用转义符!

foreach控制结构

  • 和c++中的增强for循环类似。在这里,perl会有默认变量来接收!

Perl最喜欢用的默认变量:$_

reverse操作符

  • 操作后如果需要更数组内容,就需要用数组去接收,否则不会生效!

sort操作符

  • 此处的sort还不能很完美的支持数字的排序,因为仅仅根据ascii顺序排序的!

标量上下文与列表上下文

  • 此处想表达的是,相同的符号在不同的语境下有不同的含义!
  • 比如,数字 + 数组 得到的是 数字,数组名与数字进行比较时,数组名返回的是数组的长度

在标量上下文中使用产生列表的表达式

  • 同样是 reverse数组 操作,接收的类型不同,得到的内容就不同!
  • 如果是数组接收,以数组元素为最小单位翻转
  • 如果是标量接收,以最小字符为最小单位翻转

在列表上下文中使用产生标量的表达式

列表上下文中的

  • 如果接收的是数组类型,则可以多行输入;

习题

第4章 子程序

  • 前文用到内置的系统函数有chompreverseprint
  • 和其他语言类似,perl也可以自己定义子程序,子程序名属于独立的命名空间,调用子程序一般需要加上&

定义子程序

  • 子程序的形式,如下所示:
sub marine {$n += 1; # 全局变量$nprint "Hello, sailor number $n!\n"
}
  • 与c语言相比,perl子程序的定义可以出现在任何位置,也不需要出现函数的声明;
  • 如上的子程序,操作的是全局变量,也就是说,前文用到的都是全局变量

调用子程序

  • 调用子程序,又可以叫呼叫子程序
  • 子程序名前面加上&就可以调用,如调用上面的子程序可以用&marine;
  • 如果学过c/c++,不知道这里是否可以理解为取内存中的地址,然后执行?

返回值

  • 调用子程序都会有返回值
  • 每次写返回值表达式显得费时费力
  • perl的返回值简化为,返回子程序执行过程中最后一次运算的结果
  • 小心检查最后的返回值是不是你想要的内容!你晓得吧!

参数

  • 在调用的传参时候,perl会自动参数劣列表转化为数组变量@_;
  • 如下定义的子程序,可以使用&max(10,15);这样的形式进行传参调用!
sub max {if(@_[0] > @_[1]){$_[0];} else {$_[1];}
}

子程序中的私有变量

  • 使用my定义私有变量,如下所示
sub max {my($m, &n);    # 该语句块中的新私有变量($m, &n) = @_; # 将该参数赋值给变量if ($m > $n) { $m } else { $n }  # 只有写成一行时,内部的分号才可以省略
}
  • 当然定义和初始化可以放在一行语句内,如下:
sub max {my($m, &n) = @_; # 对子程序的参数命名if ($m > $n) { $m } else { $n }  # 只有写成一行时,内部的分号才可以省略
}

变长参数列表

  • 可以在子程序内部开头判断传入参数的个数,是否符合预期!
sub max {if (@_ != 2) {print "WARNING!应该传入两个参数!"}my($m, &n) = @_; # 对子程序的参数命名if ($m > $n) { $m } else { $n }  # 只有写成一行时,内部的分号才可以省略
}

改进版的&max子程序

  • 这里其实就是选择比较法,需要理解的就是@_$_;
  • @_:子程序参数列表
  • $_:foreach循环读到的值
#!/usr/bin/perl -wsub max{my($max_so_far) = shift @_;foreach (@_) {if ($_ > $max_so_far) {$max_so_far = $_;}}$max_so_far;
}$maximum = &max(3, 5, 10, 4, 6);
print $maximum;

空列表参数

  • 需要注意的是,返回值可能为undef

用my声明的词法变量

  • my操作符并不会更改变量赋值时的上下文!
my($num) = @_; # 列表上下文,和($num) = @_;相同
my $num  = @_; # 标量上下文,和 $num  = @_;相同
  • my操作符不加括号时,只能声明靠近的单个词法变量!
  • 推荐使用my操作符定义自己的私有变量

use strict 编译指令

  • 开启这个编译指令,就要求在自定义变量声明前,必须加上my
  • use strict;:强制使用严格、良好的编程风格
  • use v5.12:自动加载strict编译指令
  • 大部分人的建议:比屏幕长的程序都应该加上use strict;

return操作符

  • 满足条件后,终止子程序!

省略与号

  • 在调用子程序时,传入参数时,可以完全省略&:编译器能明显感知到调用的是子程序
  • 自定义子程序,如果命名与内置函数重名,调用时一定要加上&

非标量返回值

  • 返回值可以是标量,也可以是列表!

持久化私有变量

  • 此处引入关键字state,在子程序中,可以一直存在,小编认为是c语言形式的static的修饰,仍然在全局区!

子程序签名

  • 乍一看,这个特性的加入,使其表现形式越来越像c语言函数的写法

习题


第5章 输入与输出

读取标准输入

  • 行输入操作符:<STDIN>与Perl的默认变量$_之间并无直接关联!
  • comp:截掉最后的换行符
  • defined:可以用来判断是否读取到末尾!
  • 下面有两个程序,执行效果相同,但他们的原理真的相同吗?
  • while实现的:
while(<STDIN>) {print "I saw $_";
}
  • foreach实现的:
foreach(<STDIN>) {print "I saw $_";
}
  • 结果就是,不一样:foreach是先把数据全部读进来;而while是读一行执行一行;如果要处理400MB数据,估计还是选择while好一点!

来自钻石操作符的输入

  • 钻石操作符<>的名字竟然是Larry的女儿命名的!
  • 钻石操作符是行输入操作符的特例,通常会处理所有的输入,所以在程序中一般只出现一次!
  • 下面展示两个相同功能的代码!
  • 代码1:
while(<>){chomp;print "It was $_ that I saw!\n";
}
  • 代码2:
while(defined($line = <>)){chomp($line);print "It was $_ that I saw!\n";
}

双钻石操作符

  • 如果命令行传入的文件名中包含==管道符|==等特殊字符,就会引发管道等特殊操作。
  • 因此引入<<>>双钻石操作符,功能没变

调用参数

  • 钻石操作符并不会检查命令行参数,其实也只是把命令行参数存放到@ARGV
  • 因此,可以通过修改@ARGV的内容,强制修改钻石操作符要读取的内容
@ARGV = qw{larry moe curly}; #强制让钻石操作符只读取这三个文件
while(<>){chomp;print "It was $_ that I saw in some stooge-link file!\n"
}

输出到标准输出

  • 下面两种打印输出有什么区别?
  • print @array;
  • print “@array”;
  • 第二行输出的时候,会在元素之间添加空格;
  • 行缓冲,也是是用换行符来进行刷新的!
  • print加括号和不加括号的区别,注意!

用printf格式化输出

  • 这里和c语言的格式高度类似,printf使用后面的括号是选择性的,如果加上,和C语言就一样了!
  • 参数宽度也可以作为参数另外指定!
  • 如下的格式:
#!/usr/bin/perl -w
use strict;
use warnings;
print "Hello world\n";printf("这里直接是以字符串的格式输出的:\n");
printf "%*s\n", 10, "wilma";
printf("%*s\n", 10, "wilma");printf("注意,此处参数宽度用参数传入:\n");
printf "%*.*f\n", 6, 2, 3.1415926;
printf("%*.*f\n", 6, 3, 3.1415926);
  • 运行结果如下:
Hello world
这里直接是以字符串的格式输出的:wilmawilma
注意,此处参数宽度用参数传入:3.143.142

数组和printf

  • 有没有发现和python的格式化输出也一样!
  • 再一次感受到,编程思想比编程语言本身重要很多!
my @items = qw{ wilma dino pebbles };printf "printf输出添加括号:\n";
printf("The items are:\n".("%10s\n" x @items), @items);printf "printf输出不加括号:\n";
printf "The items are:\n".("%10s\n" x @items), @items;
  • 运行结果:
printf输出添加括号:
The items are:wilmadinopebbles
printf输出不加括号:
The items are:wilmadinopebbles

文件句柄

  • 注意联系I/O操作,6个保留的文件句柄:STDINSTDOUTSTDERRDATAARGVARGVOUT

打开文件句柄

open CONFIG, 'dino';  # 可读可写
open CONFIG, '<dino'; # 只读
open BEDROCK, '>fred';# 可写
open LOG, '>>logfile';# 可追加写
open CONFIG, 'dino';  # 可读可写
open CONFIG, '<', 'dino'; # 只读
open BEDROCK, '>', 'fred';# 可写
open LOG, '>>:encoding(UTF-8)', 'logfile';# 可追加写,还可以指定特定编码

以二进制方式读写文件句柄

  • 句柄前加上binmode,直接以二进制数据流的方式读写。即使在二进制文件中碰巧出现内部编码和换行符相同的字符,也不会将其当做文本文件中的换行符来处理。

异常文件句柄的处理

my $success = open LOG, '>>','logfile'; # 通过返回值可以判断是否成功?
if(!$success){# open 操作失败
}

关闭文件句柄

  • 有打开就要有关闭,close,就如C中,有malloc就要有free;C++中,有new就要有delete;

用die处理致命错误

  • die函数的参数是要发出的错误信息文本,一般会输出到标准错误流,同时让程序退出运行!
  • 注意下面程序,$!记录的是程序最后返回给操作系统的错误代码!
  • 小编怀疑,die也是由linux中系统函数perror封装的,但只是猜测
if(! open LOG, '>>', 'logfile') {die "Cannot create logfile:$!";
}

用warn发出警告信息

  • die相比,warn不会终止程序的运行!

自动检测致命错误

  • 在使用的时候,在前面加上use autodie;这种声明,就会自动判断!

使用文件句柄

  • 有点像c中的sprintf
print LOG "Captain's log, stardate 3.145159\n" #输出到文件句柄 LOG
printf STDERR "%d percent complet.\n", $done/$total * 100;

改换用于输出的默认文件句柄

  • print和printf的默认输出句柄是STDOUT,我们可以使用select BEDROCK;格式来进行切换输出句柄

重新打开标准文件句柄

  • 在重新打开了 STDERR之后,任何从Perl产生的错误信息都会送到新的文件里。但如果程序执行到die这部分的代码,那会怎样呢?也就是说,如果无法成功打开文件来接收错误信息,那么错误信息会流到哪里去?
  • 在重新打开这三个系统文件句柄 STDIN、 STDOUT或 STDERR失败时,Perl会热心地帮你找回原先的文件句柄。也就是说,Perl只有在成功打开新的句柄连接时,才会关闭默认的系统文件句柄。

用say来输出

  • 输出内容并换行时,可以使用say函数
  • 这是perl 5.10的新特性,可以多试试

标量变量中的文件句柄

  • 使用裸字和标量变量,根据需要进行选取

习题

第6章 哈希

什么是哈希?

  • 名字之前有一个美元符号,之后有一个花括号
  • sv中的关联数组

访问哈希元素

  • $hash{$some_key}

访问整个哈希

  • %作为前缀,%hash

胖剪头

  • =>左边是键,右边是值;

哈希操作函数

keys和values

my %hash = ('a' => 1, 'b' => 2, 'c' => 3);
my @k = keys %hash;
my @v = values %hash;my $count = keys %hash; # 返回键值对的个数if(%hash) {print "hash 不为空";
}

each函数

  • 遍历哈希的每个键值对,可以使用each,每次调用都会返回一个键,一个值
while (($key, $value) = each %hash) {print "$key => $value\n";
}
  • 一个推荐的函数
foreach $key (sort keys %hash){$values = $hash($key);print "$key => $value\n";# 或者,可以略去额外的 $value 变量# print “$key => $hash{$key}\n”;
}

哈希的典型应用

exists函数

  • 检查哈希中是否存在某个键
if (exists $hash{"key"}){# 存在
}

delete函数

  • 直接删除指定的键和值。如果没有这样的键,那就结束,也不会出现警告或错误提示;

哈希元素内插

foreach $person (sort keys %books) {if ($books{$person}) {print "$person has $books{$person} items";}
}

特殊哈希%ENV

  • Perl会把环境信息放到特殊哈希%ENV里面

习题

第7章 正则表达式

  • regular expression

序列

$_ = "yabba dabba doo";
if (/abba/) {print "It matched\n";
}
  • 如上所示,两个斜线就是匹配操作符号!

动手实践不同模式

  • 上面的小程序就够了

通配符

  • 点号.能匹配除换行外的任意单个字符

量词

  • 指定匹配项的的重复次数。
  • 最简单的量词是:前一个字符出现n次或0次
  • 量词*:前一个字符出现n次或0次,常用于匹配不固定长度的空白字符
  • .*:贪婪匹配,可以匹配任意非换行字符任意次

模式分组

  • 用圆括号( )将模式字符串分组
  • (.)\1:匹配连续出现的两个同样字符

择一匹配

  • |:或的关系

字符集

[a=z] # a到z的全部小写字母
[-a]  # 连字符 或者 a
[^n-z] #不是n到z的字符

简写的反义形式

[a]的相反形式可以是[^a]

简写 匹配
\d 十进制数字
\D 非十进制数字
\s 空白字符
\S 非空白字符
\h 水平空白字符(Perl 5.10起支持)
\H 非水平空白字符(Perl 5.10起支持)
\v 纵向空白字符(Perl 5.10起支持)
\V 非纵向空白字符(Perl 5.10起支持)
\R 一般化的行结尾符号(Perl 5.10起支持)
\w 单词字符
\W 非单词字符
\n 换行符(不是真正的简写)
\N 非换行符(Perl 5.18 起属于稳定特性)

Unicode字符属性

锚位

  • \A:匹配字符串的绝对开头
  • \z:匹配字符串的绝对末尾
  • \b:单词锚位,匹配单词边界

习题


第8章 用正则表达式进行匹配

用m//进行匹配

  • 模式匹配操作符:m( )m< >m{ }m[],其中选择斜线作为定界符时,一般省略前面的m,变成了/ /

模式匹配修饰符

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

/s匹配任意字符

  • /.*/s:可以匹配到换行符
  • 如果不习惯用/s修饰符,可以使用[\D\d],[\S\s]等,原理就是数字字符以及非数字字符组合就是任意字符。

/x加入辅助空白字符

  • 使用这个之后,可以在模式里使用空格或换行使得代码可读性更高!

联合使用修饰符

  • 单词匹配多想修饰符
if (/barney.*fred/is){# 同时使用 /i 和 /s# 匹配成功
}
  • 用花括号作为定界符,用vim就可以自动定位跳转
if (m{barney.*fred
}isx){     # 或同时使用 /i 、 /s 和 /x# 匹配成功
}

选择字符的解释方式

  • Perl 5.14 开始增加了一些用于告诉Perl如何解释字符意义的修饰符,主要是:对大小写的处理以及对字符集合的阐释。

行首和行尾锚位

  • ^\A一样,$\z一样
  • 如果加上/m修饰符,/^/m就会匹配字符串开头和换行符之后的内容(就是每行开头)

绑定操作符=~

  • 正则表达式默认匹配的目标文本是$_,我们可以使用绑定操作操作符=~指定要匹配的目标文本。

捕获变量

  • 捕获变量,把匹配到的内容用标量存储起来,方便调用!一般使用圆括号()进行捕获

捕获变量的存续期

  • 捕获变量的内容一般会保持到下次成功匹配为止,我们可以将其保存下来的;

禁用捕获的括号

  • 在左括号后加上?:,此时的括号仅用于分组,不再捕获匹配字符串。

命名捕获

  • 使用如下的捕获标签,可以随意移动位置,并加入更多的捕获括号!
use v5.10;my $names = 'Fred or Barney';
if ($names =~ m/(?<name1>\w+) (?:and|or)(?<name2>\w+)){say "I saw $+{name1} and $+(name2)";
}

自动捕获变量

  • $`:匹配保存之前的内容
  • $&:匹配保存 的内容
  • $’:匹配保存之后的内容
  • 修饰符/p可以对当前的表达式开启类似的自动捕获变量,变成了${^PREMATCH},${^MATCH},${^POSTMARTCH}

优先级

正则表达式优先级表

正则表达式特性 示例
元括号(分组或捕获) (···),(?:···),(?···)
量词 a*,a+,a?,a{n,m}
锚位和字符序列 abc, ^, $, \A, \b,\z,\Z
择一 a|b|c
原子 a,[abc],\d,\l,\g{2}

模式测试程序

  • 程序来源:https://www.learning-perl.com/downloads_page/
#!/usr/bin/perl
while (<>) {                   # take one input line at a timechomp;if (/YOUR_PATTERN_GOES_HERE/) {print "Matched: |$`<$&>$'|\n";  # the special match vars} else {print "No match: |$_|\n";}
}

习题

第9章 用正则表达式处理文本

s///进行替换操作

s/st1/st2; #试图将st1替换为st2

/g进行全局替换

s/\s+/ /g;  # 将任意连续的空白转换成单一空格
s/\A\s+//g; # 将开头的空白字符替换成空字符串
s/\s+\z//g; # 将结尾的空白字符替换成空字符串
s/\A\s+|\s+\z//g; #去除开头和结尾的空白字符

不同的定界符

  • m//qw//一样,可以改变s///的定界符

替换操作的修饰符

  • 除了/g修饰符外,我们还可以把用在普通模式匹配中的/i/x/s修饰符用在替换操作中

绑定操作符

  • =~s///指定不同的替换目标

非破坏性替换

  • 如果需要同时保留原始字符串和替换后的字符串,该怎么办?
  • 复制拷贝一份再替换
my $original = 'Fred ate 1 rib';
my $copy = $original;
$copy =~ s/\d+ ribs?/10 ribs/;
  • 等价于
(my $copy =  $original )=~ s/\d+ ribs?/10 ribs/;
  • perl 5.14增加了一个/r字符串,就会保留原来字符串中的值不变,把替换结果作为替换操作的返回值返回
use v5.14;
my $copy =  $original =~ s/\d+ ribs?/10 ribs/r;

大小写转换

  • \U将它后面的所有字符转成大写的
  • \L将它后面的所有字符转成小写的
  • 默认情况下,它们会影响之后全部的(替换)字符串,可以用\E关闭大小写转换的功能;
  • 使用小写\l\u,它们只会影响紧随其后的第一个字符;
  • 同时使用\u\L来表示"后续字符全部转为小写的,但首字母大写”

元字符转义

s/\(\(\(Fred/fred/# 使用\Q简化形式
s/\Q(((Fred/fred/
\

split操作符

  • 格式如下:
my @fields = split /separator/, $string;
  • 例子如下:
  • 注意第二行和第三行
my @fields = split /:/,"abc:def:g:h";    # 得到("abc","def","g","h")
my @fields = split /:/,":::a:b:c:::"     # 得到("","","","a","b","c")
my @fields = split /:/,":::a:b:c:::",-1  # 得到("","","","a","b","c","","","")
  • 默认split会以空白字符分割$_中的字符串;
my @fields = split; # 基本等效于split /\s+/, $_;

join函数

  • join会把胶水涂进每个片段之间并返回结果字符串
my $x = join ":",4,6,8,10,12; # $x 为 “4:6:8:10:12”
my @values = split /:/,$x;    # @values 为(4,6,8,10,12)
my $z = join "-", @values;    # $z为 “4-6-8-10-12”

列表上下文中的m///

更强大的正则表达式

习题


第10章 其他控制结构

unless控制结构

  • if条件为真时执行,unless条件为假时执行

伴随unless的else语句

  • 就是if else改成了unless else

until控制结构

  • 颠倒while的条件表达式,就用until

表达式修饰符

  • 简化代码书写
  • 即使条件表达式写在后面,它也会先执行
  • 倒装句
print "$n is a negative number.\n" if $n < 0;
if($n < 0) {print "$n is a negative number.\n";
}

裸块控制结构

  • { }主要是为变量限制作用域,和c++一样

elsif子句

  • 注意不是elseif

自增与自减

  • 前置后置,自增自减。

for控制结构

  • 和c语言写法一致

for和foreach之间的秘密

  • for和foreach实际上是等价的。括号中有两个分号,就把它当做for,若没有分号,就把他当做foreach

循环控制

last操作符

  • 和c语言的break一样,退出循环

next操作符

  • 和c语言的continue一样,跳过本次循环

redo操作符

  • 这不是goto语句封装好的吗?

带标签的块

  • 这不就是verilog中的程序块别名吗?

条件操作符

  • 三目运算符? :
  • expression ? if_true_expr : if_false_expr

逻辑操作符

  • 全套的逻辑操作符

短路操作符的返回值

  • 短路操作符可以改为三目运算符

使用部分求值操作符的控制结构

  • &&||//?:都是根据左边的值确定要不要执行右边的表达式

习题


第11章 Perl模块

  • 如何使用现有的模块,目的是熟悉使用CPAN完成自己的任务!

寻找模块

  • 寻找那些没有随Perl发布的模块,可以到CPAN Seach网站(http://search.cpan.org)或MetaCPAN(http://www.metacpan.org)

安装模块



使用简易模块

习题

第12章 文件测试

文件测试操作符

stat和lstat函数

loacltime函数

位运算操作符

习题


第13章 目录操作

当前工作目录

  • 借助标准模块之一Cwd模块,查看当前的工作目录是哪个
use v5.10;
use Cwd;
say "The current working directory is ",getcwd();
  • 可以使用标准模块之一File::Spec实现相对路径和绝对路径之间的相互转换\

修改工作目录

  • chdir:和shell中的cd一个意思
chdir '/etc' or die "cannot chdir to /etc :$!";
  • 可以使用File::HomeDir模块去往特定用户的主目录,他支持大部分操作系统。

文件名通配

  • 文件名通配:glob
my @all_file = glob '*';
my @pm_file = glob '*.pm';
  • Perl内置的glob并非唯一选择,我们可以用File::Glob模块提供各式兼容和扩展的文件名通配。

文件名通配的隐式语法

my @all_files = <*>; # 效果和这样的写法完全一致: my  @all_files = glob "*";
  • Perl 会把尖括号内出现的变量替换成它的值,类似于双引号内字符串的变量内插,如下
my $dir = '/etc';
my @dir_file = <$dir/* $dir/.*>;

目录句柄

  • 一个例子
my $dir_to_process = '/etc';
opendir my $dh, $dir_to_process or die "Cannot open $dir_to_process:$!";
foreach $file (readdir $dh) {print "one file in $dir_to_process is $file\n";
}
closedir $dh;
  • 使用裸字DIR
my $dir_to_process = '/etc';
opendir DIR, $dir_to_process or die "Cannot open $dir_to_process:$!";
foreach $file (readdir DIR) {print "one file in $dir_to_process is $file\n";
}
closedir DIR;

文件和目录的操作

删除文件

  • unlink:
unlink 'slate', 'bedrock','lava';
unlink qw{slate bedrock lava};unlink glob '*.o';
  • unlink返回的是成功删除的文件数目,我们可以把他们放到循环依次删除并检查
foreach my $file (qw(slate bedrock lava)) {unlink $file or warn "failed on $file:$!\n";
}

重命名文件

  • rename 'old','new';
  • 借用胖剪头=>:
  • 如何批量把名称是.old结尾的文件改名为以.new结尾?
foreach my $file (glob "*.old") {my $newfile = $file;$newfile =~ s/\.old$/.new/;if (-e $newfile) {warn "can't rename $file to $newfile: $newfile exists\n"} elsif(rename $file => $newfile) {# 改名成功,什么都不需要做} else {warn "rename $file to $newfile failed:$!\n";}
}
  • 循环里的前两行还可以修改为
my ($newfile = $file) =~ s/\.old$/.new/;
  • 也可以在Perl 5.14里面加上/r修饰符,
use v5.14;
my $newfile = $file =~ s/\.old$/.new/r;

链接与文件

  • 与Linux操作系统的文件作对比吧,inode节点等,确定是软链接这个说法吗?(之前有老师强调过,没有软链接这一说,是符号链接和硬链接)

创建和删除目录

  • 创建失败返回设定值
mkdir 'fred', 0755 or warn "Cannot make fred directory: $!";
  • 移除空目录
foreach my $dir(qw{fred barney betty}) {rmdir $dir or warn "cannot rmdir $dir:$!\n";
}
  • 如果要创建临时目录或文件,可以用File::Temp模块

修改权限

  • chmod不支持linux中a+x这种格式,除非从CPAN安装了File::chmod.
  • 常规格式如下:
chmod 0755, 'fred','barney';

修改文件属主

chown $user, $group, glob '*.o';

修改时间戳

my $now = time;
my $ago = $now - 24 * 60 * 60; # 一天的秒数
utime $now, $ago, glob '*';    # 将最后访问时间改为当前时间,最后修改时间改为一天前

习题


第14章 字符串与排序

用index查找子字符串

my $where = index($stuff, "wor");

用substr操作子字符串

my $part = substr($string,$initial_position, $length);

用sprintf格式化字符串

my $money = sprintf "%.2f", 2.4997;

高级排序

  • 飞碟操作符’<=>’
my @descending = sort {$b <=> $a} @some_numbers;

按哈希值排序

my %score = ("barney" => 195, "fred" => 205, "dino" => 30);
my @winners = by_score keys %score;

按多个键排序

  • 例子1:
my %score = ("barney" => 195, "fred" => 205, "dino" => 30, "bamm-bamm" => 195,);
my @winners = by_score_and_name keys %score;sub by_score_and_name {$score{$b} <=> $score{$a} #先按照分数降序排列or$a cmp $b #分数相同的再按名字的ASCII码序排列
} @winners
  • 例子2:
@patron_IDs = sort{&fines($b) <=> &fines($a) or$items($b) <=> $items($a) or$family_name{$a} cmp $family_name{$b} or$personal_name{$a} cmp $family_name{$b} or$a <=> $b;
} @patron_IDs;

习题

第15章 进程管理

习题


第16章 高级Perl技巧

习题

后记

  • 本文内容只是记录了小编想学习的部分,其他部分暂时忽略。
  • 要是工作中需要的话,再深究!

《Perl语言入门》学习笔记相关推荐

  1. 第二行代码学习笔记——第六章:数据储存全方案——详解持久化技术

    本章要点 任何一个应用程序,总是不停的和数据打交道. 瞬时数据:指储存在内存当中,有可能因为程序关闭或其他原因导致内存被回收而丢失的数据. 数据持久化技术,为了解决关键性数据的丢失. 6.1 持久化技 ...

  2. 第一行代码学习笔记第二章——探究活动

    知识点目录 2.1 活动是什么 2.2 活动的基本用法 2.2.1 手动创建活动 2.2.2 创建和加载布局 2.2.3 在AndroidManifest文件中注册 2.2.4 在活动中使用Toast ...

  3. 第一行代码学习笔记第八章——运用手机多媒体

    知识点目录 8.1 将程序运行到手机上 8.2 使用通知 * 8.2.1 通知的基本使用 * 8.2.2 通知的进阶技巧 * 8.2.3 通知的高级功能 8.3 调用摄像头和相册 * 8.3.1 调用 ...

  4. 第一行代码学习笔记第六章——详解持久化技术

    知识点目录 6.1 持久化技术简介 6.2 文件存储 * 6.2.1 将数据存储到文件中 * 6.2.2 从文件中读取数据 6.3 SharedPreferences存储 * 6.3.1 将数据存储到 ...

  5. 第一行代码学习笔记第三章——UI开发的点点滴滴

    知识点目录 3.1 如何编写程序界面 3.2 常用控件的使用方法 * 3.2.1 TextView * 3.2.2 Button * 3.2.3 EditText * 3.2.4 ImageView ...

  6. 第一行代码学习笔记第十章——探究服务

    知识点目录 10.1 服务是什么 10.2 Android多线程编程 * 10.2.1 线程的基本用法 * 10.2.2 在子线程中更新UI * 10.2.3 解析异步消息处理机制 * 10.2.4 ...

  7. 第一行代码学习笔记第七章——探究内容提供器

    知识点目录 7.1 内容提供器简介 7.2 运行权限 * 7.2.1 Android权限机制详解 * 7.2.2 在程序运行时申请权限 7.3 访问其他程序中的数据 * 7.3.1 ContentRe ...

  8. 第一行代码学习笔记第五章——详解广播机制

    知识点目录 5.1 广播机制 5.2 接收系统广播 * 5.2.1 动态注册监听网络变化 * 5.2.2 静态注册实现开机广播 5.3 发送自定义广播 * 5.3.1 发送标准广播 * 5.3.2 发 ...

  9. 第一行代码学习笔记第九章——使用网络技术

    知识点目录 9.1 WebView的用法 9.2 使用HTTP协议访问网络 * 9.2.1 使用HttpURLConnection * 9.2.2 使用OkHttp 9.3 解析XML格式数据 * 9 ...

  10. 安卓教程----第一行代码学习笔记

    安卓概述 系统架构 Linux内核层,还包括各种底层驱动,如相机驱动.电源驱动等 系统运行库层,包含一些c/c++的库,如浏览器内核webkit.SQLlite.3D绘图openGL.用于java运行 ...

最新文章

  1. 获取长度length_lab、labE、la、laE、ll、llE 钢筋锚固搭接长度6项参数的相互关系...
  2. Mesos源码分析(8): Mesos-Slave的初始化
  3. C语言实现小时候经常做的智力测试题
  4. tomcat ajp协议安全限制绕过漏洞_国家信息安全漏洞共享平台发布Apache Tomcat漏洞安全公告...
  5. fibonacci数列的性质(ZOJ3707)
  6. PCB设计的基本步骤
  7. 上海java 开发培训_上海十大java培训
  8. mysql5.5怎么升级补丁_mysql 5.5升级到5.7版本操作流程
  9. windows10+ubuntu16.04双系统搭建
  10. js数组获取index_想自学JS吗?想提升JS底层原理吗?76张脑图带你彻底搞懂原生JS...
  11. 计算机网络传媒介,2.3 网络传输媒介 - 第2章 计算机网络硬件基础 - 《计算机网络技术与应用》 - 倾心驿站 - 恰教程网...
  12. Stata: 空间权重矩阵的构建
  13. golang中文字符编码转换
  14. fw313r手机登录_迅捷(FAST)fw313r路由器初始密码_登录密码是多少?-192路由网
  15. 联想笔记本电脑insert键占用,当鼠标变成小方块时,如何解决
  16. oracle中字段类型为date存储数据精确到时分秒的问题
  17. 30行代码用python实现软件翻译
  18. STM32标准库、HAL库特点与应用
  19. 计算机二级C语言考试Tips
  20. 解决win10安装virtualBox没有host-only设置问题

热门文章

  1. 【专题】CSDN下载频道3月热门资源top100汇总
  2. python基于情感词典的情感分析
  3. java小游戏制作(maxfo)
  4. Java编程思想读书笔记(一)第1~13、16章
  5. kettle-如何在kettle中编写java代码
  6. CSDN博客代码块语法高亮
  7. Excel图表之道—如何制作专业有效的商务图表(远离难看的图表,让客户满意,给自己加薪)...
  8. 佳能g2810提示5b00_佳能G2810打印机清零软件5B00 5b01废墨清零1700代码
  9. Map转json遇到一些问题
  10. 微信开发者工具下载及APPID获取