Perl学习笔记(二)

第七章:正则表达式

Q1:Perl如何使用正则表达式?常用的正则表达式有哪些?

答:[1]要匹配某个模式(正则表达式)$_的关系,可以将模式放在正斜线(//)之间,如下:
$_ = yabbadabba doo;
if(/abba/){
print
Itmatched!\n;
}

表达式/abba/将在$_寻找这四个字母。如果找到,则返回true在本例中,它出现了不止一次,但结果没什么不同。总之,
如果找到了,则匹配上;如果没找到,则没匹配上。

由于模式匹配通常返回 true false因此经常用在if while 的条件表达式部分。

[2]

[2.1]简单的模式

[2.1.1](.)通配符

(.)是通配符,它可以匹配任何单个的字符,但不包括换行符(\n)因此,模式/bet.y/将匹配betty同时也匹配betsy, (.)只匹配一个字符。

[2.1.2]星号(*)

星号(*)表示匹配前一项次或者多次。因此,/fred\t*barney/将匹配上fred barney
之间有任意个制表位(tab)的字符串。

[2.1.2](+)

(+)的意思是可
以匹配前面一项的一个或多个:/fred +barney/意思是fred barney 之间由空格分开,且只能是空格。至少是一个

[2.1.3]问号(?)

问号(?)其含义是前面一个项出现一次,或者不出现。也就是说,前面这个项出现 1 次或者 0次,此外不会有其它情况。因此,/barm-?bamm/只匹配:bamm-bamm bammbamm这很容易记住:前面的这个项,出现?或者不出现?

[2.1.4]括号(())用来表示分组

模式/(fred)+/能匹配上像fredfredfred 这样的字符串

[2.1.5]竖线(|)

竖线(|)在这种用法中通常被读作“或( or”,意思是匹配左边的或者右边的。如果竖线左边没有匹配上,则匹配右边。因此,/fred|barney|betty/将匹配出现过fred或者barney或者betty 的字符串。

 

[2.2]字符类

[2.2.1]方括号[]

可以匹配上括号内出现的任意单个字符。它匹配一个字符,但这个字符可以是列中的
任意一个。

例如,字符类[abcwxyz]可以匹配上括号内七个字母中的任意一个。

[2.2.2]连字号(-)

为了方便,我们可以使用连字号(-)来表示某个范围的字母,因此上例也可以写做[a-cw-z]

[2.2.3]符号^

字符类前使用符号^将取此字符类的补集。也就是说,[^def]]将匹配上这三个字符中之外的任意单个字符。[^n\-z]将匹配上n, -, z 之外的任何字符。

[2.2.4]字符类的简写

任何数字的类,[0-9]可以被简写为:\d

\w 被称作word’字符:[A-Za-z0-9_]

\s 对于匹配空白(whitespace将非常方便

它等价于[\f\t\n\r]其含 5 个空白字符:格式符(form-feed);制表符(tab)换行符,回车,以及空格符。

 

[2.2.5]简写形式的补集

三种简写形式的补集[^\d],[^\w], [^\s]

等价于\D, \W, \S

 

第十章:更多控制结构

Q1:perl中除了IF控制结构还有哪些控制结构?各控制结构的语法定义是怎样的?

答:

[1.1]unless控制结构

unless的含义是:除非条件为真,否则执行块中的代码。这和在if 语句的条件表达式前面加上!(取反)所得结果是一样的。

unless($mon =~ /^Feb/){
print “This month has at least thirty days.\n”;
}else{
print “Do you see what’s going on here?\n”;
}

等价于:

if($mon=~ /^Feb/){
print “Do you see what’s going on here?\n”;
}else{
print “This month has at least thirty days.\n”;
}

[1.2]until控制结构

有时,希望将while 循环的条件部分取反。此时,可以使用until
until($j >$i){
$j *=2;
}
这个循环一直执行,直到条件表达式的返回值为真为止。它和while 循环非常类似,只是在条件为假时重复执行,而不是在条件为真的情况下执行。

 

[1.3]裸块控制结构

被称为“裸的”块是指没有关键字或条件的块。

假如有一个while 循环,大致如下:
while(condition){
body;
body;
body;
}
将关键字while 和条件表达式去掉,则有了一个“裸的”块:
{
body;
body;
body;
}
“裸的”块看起来像while foreach 循环,除了它不循环外;它执行“循环体”一次,然后结束。它根本就没循环!

 

[1.4]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”;
}

[1.5] for控制结构

for($i= 10; $i >=1; $i--){
print “I can count down to $i\n”;
}

 

[1.6]循环控制

[1.6.1] last操作

last 会立刻结束循环。(这同 C 语言或其它语言中的break”语句类似)。它从循环块中“紧急退出”。当执行到last循环即
结束,如下例:
#输出所有出现fred 的行,直到遇见_ _END_ _标记
while(<STDIN>){
if(/_ _ END_ _/){
#
这个标记之后不会有其它输入了
last;
}elsif(/fred/){
print;
}
}
##last
跳转到这里##

 

[1.6.2]next操作

有时还不希望结束循环,但本次循环已经结束。这种情况下,next 是非常适用的。它跳到当前循环块的最后面(块内)◆。
next 之后,又会进入下一轮循环(这和 C 或者类似语言的continue”相似):
◆我们这里又撒了一个小谎。事实上, next 跳到循环的conttinue(通常省略)块的开头处。参见perlsyn 了解详细的信息。
#分析输入文件的单词
while(<>){
foreach(split){ #
$_分拆成单词,并依次赋给$_
$total++;
next if/\W/; #
不是“words的被跳过
$valid++;
$count{$_}++; #
对每个单词进行计数
##next
跳到这里##
}
}
print
totalthings = $total, valid words = $valid\n;
foreach $word (sort keys %count){
print
$wordwas seen $count{$word} time.\n;
}
这几乎是到目前为止所出现过的最复杂例子,让我们一步一步地分析它。

last, next 可以在这 5 种循环中使用:for, foreach, while, until, 或者“裸”块。如果块是嵌套的,next 在最里层工作。

 

[1.6.3] redo操作

循环控制的第三个操作是redo它会调到当前循环块的顶端,不进行条件表达式判断以及接着本次循环。(在 C 或类似语
言中没有这种操作。)下面是一个例子:
#输入测试
my @words = qw{ fred barney pebbles dino Wilma betty } ;
my $errors = 0;

foreach(@words){
##redo
跳到这里##
print
Typethe word $_ :;
chomp(my $try = <STDIN>);
if($try ne $_){
print
sorryThatsnot right.\n\n;
$errors++;
redo; #
跳转到循环顶端
}
}
print
Youvecompleted the test, with $errors errors.\n;
和其它两种操作一样,redo 可以在 5种循环体内工作,当在嵌套循环体中时,它在最内层使用。

 

第十一章:文件检验

Q1: perl可针对哪些文件状态信息进行检测?分别使用的函数是什么?

答:

[1] 11-1 文件检测选项及其含义
检测选项含义
-r
文件或目录对此(有效的)用户(effective user或组是可读的
-w
文件或目录对此(有效的)用户或组是可写的
-x
文件或目录对此(有效的)用户或组是可执行的
-o
文件或目录由本(有效的)用户所有
-R
文件或目录对此用户 (real user)或组是可读的
-W
文件或目录对此用户或组是可写的
-X
文件或目录对此用户或组是可执行的
-O
文件或目录由本用户所有
-e
文件或目录名存在
-z
文件存在,大小为 0(目录恒为false
-s
文件或目录存在,大小大于0(值为文件的大小,单位:字节)
-f
为普通文本
-d
为目录
-l
为符号链接
-S
socket
-p
为管道(Entryis 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
索引节点修改时间(单位:天)
-r, -w, -x 以及-o 检测相应的属性对 effective user group ID 是否为真,它是指实际负责运行此程序的用户◆。这些检测通
过查看文件的权限位(permission bits)。如果你的系统使用访问控制列表(Access Control Lists(ACLs))则这些测试就使用它。
这些选项检测其权限,但并非说这种操作一定能进行的。例如,-w

 

示例:

die“Oops! A file called ‘ $filename’ already exists.\n”
if –e $filename;

 

[2] stat lstat函数

虽然这些检测项可以很好的给出文件或文件句柄相应参数的属性,但它们还没有包括所有的信息。例如,它们不能给出文
件的连接数,或者所有者的user ID(uid) 要得到文件的其余信息,可以使用stat 函数,其返回Unix 系统调用stat 时相同的
值(比你想知道的还多)

my($dev, $ino, $mode, $nlink, $uid, $gid, $rdev, $size, $atime, $mtime, $ctime,$blksize, $blockes)
= stat($filename);

$dev$ino
文件的设备号和索引节点号。它们组成了文件的“牌照(licenseplate)”。即便它有多个名字(硬连接(hard link)),
备号和索引节点号的组合仍是唯一的。

$mode
文件的权限位以及一些其它的位。如果使用过Unix 命令ls l 来得到文件的详细信息,其每一行由类似于rwxr-xr-x
头。这些字母以及连接线( 9 个)◆是指文件的权限,它们对应于$mode中最不重要的位,在本例为0755其它位,
除了这最低的9 位外,是指文件的其余信息。 mode 需要将它和本章后面的位操作结合起来使用。

$nlink
文件或目录的(硬)连接数。是指被检测项真实名字的个数。对于目录其值总是2 或者更大的数,而对于文件(通常)
1我们将在第十二章中讨论建立文件的连接,到你你将更清楚。对于ls l其为紧接权限位串的数字。
$uid
$gid
指文件所有权的user ID group ID
$size
返回其大小,单位:字节,s 文件检测项相同。
$atime, $mtime,
$ctime
这三个时间,它们按照系统的时间格式: 32 位,表示从某个时刻到现在所经过的秒数,这个时刻是记录系统时间的一
个任意值。Unix 和别的某些系统中,这个时刻从世界时间 1970 年第一个午夜开始,但在某些系统中,这个时刻可
能不同。本章后面有更多的关于如何将时间转换为有用格式的信息。
stat 的参数是符号连接时,其返回的信息是此符号连接指向的实体的信息,而非符号连接本身的信息,除非此符号连接
所指向的内容不能被访问。如果需要得到(几乎是没用的)符号连接本身的信息,可以使用lstat 代替stat它按照相同的
顺序返回同样的值)。如果其操作数不是符号连接,lstat stat 返回的值相同。
同文件检测(filetests)一样,stat lstat 的默认参数为$_意指stat 系统调用将针对$_所对应的文件进行操作。

 

[3]localtime函数

my($sec,$min, $hour, $day, $mon, $year, $wday, $yday, $isdst)
= localtime $timestamp;

 

 

第十二章:目录操作

Q1perl提供的文件目录操作有哪些?请分别列出程序实例。

答:

[1]改变当前工作目录

chdir可以改变工作目录。它和Unix shell 下的cd 命令类似:

chdir“/etc” or die “cannot chdir to /etc: $!”;

[2]获取目录

my$dir_to_process = “/etc”;

opendirDH, $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;

[3]递归目录

File::Find

[4]删除文件

由于unlink 以一个列表作为操作,glob 返回列表,因此可以将它们结合起来,一次删掉多个文件:
unlink glob *.o;

或者

foreachmy $file (qw(slate bedrock lava)) {
unlink $file or warn “failed on $file: $!\n”;
}

 

[5]重命名文件

将一个给定文件重命名可以很简单的使用rename 函数做到:
rename old, new;

 

[6]创建和删除目录

在一个目录下创建新目录是很容易的。使用mkdir 函数:

mkdir“fred”, 0755 or warn “Cannot make fred directory: $!”;

要删除一个空的目录,按照类似于unlink 函数的方法使用rmdir 函数:
rmdir glob fred/*;#删除fred/下面所有的空目录
foreach my $dir (qw(fred barney betty)){
rmdir $dir or warn
cannot rmdir $dir: $! \n;
}
unlink 一样,rmdir 返回删除的目录个数,如果一次删除一个,则会在失败时设置合理的$!值。

 

[7]修改权限

chmod0755, “fred”, “barney”;

 

[8]修改所有者

如果操作系统允许,你可以使用chown 函数改变一批文件的所有者及所在的组。所有者及组是同时改变的,它们两个分别有一个数字值 user-ID group-ID例如:

my$user = 1004;
my $group = 100;
chown $user, $group, glob “*.o”;

 

[8]改变时间戳

一个时间戳方便使用的值是“现在(right now)”,time 函数返回的值,其格式是合适的。更新当前目录下的所有文件,使它们看起来是昨天修改的,而访问时间为现在,可以如下做到:
my $now = time;
my $ago = $now -24*60*60; #
一天的秒数
utime $now, $ago, glob
*; #设成当前访问的,一天之前修改的

 

 

第十三章:字符串和排序

Q1:perl如何定位一个字符串中某个子中?

答:[1]index函数总是报告子串出现的第一个位置。可以使用可选的第三个参数要求它从后面的某个地方开始查询,它会告诉index从什么位置开始:

my$stuff = “Howdy world! ”;
my $where = index($stuff, “wor”);

my$stuff = “Howdy world!”;
my $where1 = index($stuff, “w”); #$where1
得到 2
my $where2 = index($stuff, “w”, $where+1); #$where
得到6
my $where3 = index($stuff, “w”, $where+1); #$where
-1(没有找到)

[2]有时,你可能想知道某个子串最后出现的位置

rindex函数也有可选的第三个参数;此时,它给出的是可能的最大值:
my $fred = Yabbadabba doo!;
my $where1 = rindex($fred,
abba); #$where1 得到7
my $where2 = rindex($fred,
abba, $where - 1); #$where2 得到1
my $where3 =rindex($fred,
abba, $where2-1); #$whrere3 得到-1

 

 

Q2perl如何截取子串?

答:my $mineral = substr(“Fred J.Flintstone”, 8, 5); #得到“Flint”

my $out= substr (“some very long string”, -3, 2); # $out 得到“in”

 

Q3perl如何对给定的字符串进行格式化,比如统一大写,统一小写等?

my$data_tag = sprintf “%4d/%02d/%02d %02d:%02d:%02d”,$yr, $mo, $da, $h, $m, $s;

my$money = sprintf “%.2f”, 2.49997;

 

 

Q4perl如何对字符串内部进行排序?

 

Q5perl的高级排序体现在什么地方?如何实现?为什么?如果不这样实现还有什么其它方法?

答:cmp 或者ó

@patrons_IDs= sort {

&fines($b)<=> &fines($a) or

$items{$b}<=> $items{$a} or

$family_name{$a}cmp $family_name{$a} or

$personal_name{$a}cmp $family_name{$b} or

$a<=> $b

}@patron_IDs;

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值