xajh32y 发表于 2015-12-25 15:36:45

《Beginning Perl》读书笔记3:6~10章

第6章:子过程/函数

[*]声明:subfunction_name;
[*]定义:subfunction_name {...}
[*]函数调用同C:


[*]

[*]example_subroutine();或example_subroutine;
[*]example_subroutine('Perl is', 'my favorite', $language);或example_subroutine 'Perl is', 'my favorite', $language;
[*]调用时需保证之前已有声明/定义



[*]返回值:函数的最后一行代码可以写表达式作为返回值,例如写$total;也可以使用return语句在函数体中的任意位置返回返回值
[*]函数内部通过@_变量访问传入参数:
[*]Perl中按引用传参,改变输入参数将影响函数外的变量


[*]实现默认参数值的小技巧:

sub log_warning {
my $message = shift || "Something's wrong";
my $time = shift || localtime; # Default to now.
print "[$time] $message\n";
}

[*] 实现参数命名的小技巧:

[*]调用:logon(username => $name, password => $pass, host => $hostname);
[*]定义:


sub logon {
die "Parameters to logon should be even" if @_ % 2;
my %args = @_;
print "Logging on to host $args{hostname}\n";
...
}第7章:正则表达式

[*]正则表达式以双斜线对//包裹,//中可以使用变量,变量将被代换为对应的值
[*]正则式匹配:str =~ /re/若str匹配/re/成功为true,反之false;!~则与=~相反
[*]/re/等价于$_ =~ /re/
[*]进行匹配后,可以使用$1,$2,$3...获得字符串中匹配成功的子串

[*]因为不知道有多少个匹配成功的子串,所以需要用defined算符一一检验$1, $2, $3是否已定义,stupid

[*]//正则式中以下元字符(metacharacter)需要使用\转义:. * ? + [ ( ) { ^ $ | \ /
[*]\Q可用于关闭元字符,\E用于结束\Q。\Q...\E之间的部分可自由使用上一要点中提到的元字符
[*]锚点^表示从字符串起始处匹配,而$则表示匹配至字符串末尾结束
[*][]可定义字符集,例如匹配a,b或c,匹配0,1,2,3,4,5,6,7,8,9任一。[]中使用^表达反义,即[^eo]可匹配除e,o外任意字符
[*]几个等价:\d等价于,\w等价于,\s等价于[ \t\n\r\f],\D等价于[^0-9],\W等价于[^0-9A-Za-z_],\S等价于[^ \t\n\r\f],.等价于任意字符(换行符除外)
[*]|可用于表示或,例如yes|maybe可匹配yes或maybe,ye(s|t)匹配yes或yet
[*]?意味?前面的记号出现0或1次,例如(word )?is可匹配word is和is
[*]+则为1次及1次以上,*为任意次(包含0次)

[*]/bea?t/匹配beat和bet
[*]/bea+t/匹配beat, beaat, beaaat...
[*]/bea*t/匹配bet, beat, beaat, beaaat...

[*]{}则可以定义具体的出现次数,例如\s{2,3}可匹配2个空格,也可匹配3个空格。{x}代表x次,{x,}则代表x次及x次以上
[*]正则式匹配器的工作原则:

[*]一旦匹配无法继续(下一个字符无法满足正则式定义),立即停止匹配
[*]一旦匹配成功,马上结束匹配
[*]遇+*?三个字符时取最长匹配,即匹配至无法匹配时再匹配之后的正则式与字符串
[*]最近分支原则:若存在分支匹配(例如或ye(s|t)这种情况)则从前向后依次尝试,若尝试失败则取下一个,直到成功匹配或所有情况匹配失败

[*]使用正则式进行替换:str =~ s/find/replace/;可用于将str中满足find模式的首个子串替换为replace,若不指定str,执行s/find/replace/;为对$_操作,在末尾加g修饰符可替换所有子串

$_ = "Awake! Awake! Fear, Fire, Foes! Awake! Fire, Foes! Awake!";
s/Foes/Flee/;
print $_,"\n";
输出:
Awake! Awake! Fear, Fire, Flee! Awake! Fire, Foes! Awake!  

$_ = "there are two major products that come out of Berkeley: LSD and UNIX";
s/(\w+)\s+(\w+)/$2 $1/g;
print $_, "?\n";
输出:
are there major two that products out come Berkeley of: and LSD UNIX?

[*]类似q//和qq//,//和s///也可以使用别的分隔符,当在匹配(//)中使用其他分隔符时,需要使用m作为前缀,例如m/^\s*/;m#^\s*#;m{^\s*};等,而s/old text/new text/g;则可以写为s{old text}{new text}g;也可以出于清晰写为:
s{old text}
{new text}g;
再如s/\/usr\/local\/share\//\/usr\/share\//g;可写为s#/usr/local/share/#/usr/share/#g;

[*]修饰符

[*]/m将字符串作为多行字符串处理,在这种情况下^$不再分别匹配单词首尾,而是匹配行首行尾
[*]/s将字符串作为单行字符串处理,此时.匹配包括换行符在内的所有字符
[*]/g:匹配时若有多个可匹配子串则全部匹配;替换时则替换所有可匹配子串,使用此修饰符时可使用\G锚点匹配最后一个可匹配子串的最后一个字符位置
[*]/x允许以多行方式书写正则式,且可以添加注释

[*]split(re, str)将str按照re分为多个子串,返回包含这些子串的列表。不指定str则默认对$_操作。例如split /:/, “kake:x:10018:10020::/home/kake:/bin/bash”可得(“kake”, “x”, “10018”, “10020”, “”, “/home/kake”, “/bin/bash”)
[*]join(str, list)可用str将list中各个元素连接为一个字符串,并返回这个字符串,例如join “#”, (“kake”, “x”, “10018”, “10020”, “”, “/home/kake”, “/bin/bash”)可得“kake:x:10018:10020::/home/kake:/bin/bash”
第8章:文件与数据

[*]打开文件:open(filehandle, mode, filename)例如open(FH, '<', 'input.txt')

[*]打开成功时返回true,反之false
[*]也可以写作open(FH, '< input.txt')

[*]访问模式:>写<读>>追加
[*]close(filehandle)用于关闭文件句柄,例如close(FH);
[*]标量读入:my $line = <FH>,读入一行
[*]列表读入:my @list = <FH>,读入所有行,每行为一个列表元素
[*]特殊文件句柄:<>(称为“钻石运算符”)

[*]当未在命令行参数中指定输入文件时,为<STDIN>
[*]否则为指定的文件句柄。可指定多个文件,按指定顺序逐个打开、逐行读取

[*]@ARGV为存储命令行参数的字符串数组,例如以perl argv1.pl king crimson rocks运行时@ARGV为(‘king’, ‘crimson’, ‘rocks’)
[*]<>本质上就是用@ARGV实现的。$ARGV为<>当前文件句柄指向文件的文件名
[*]print FH list可以向FH指向的文件中输出list
[*]$|变量设置是否使用OS的输出缓冲区,默认为0(使用),设为1后不使用
[*]管道:将上一个程序的STDOUT输出接入:open(FH, '-|', command);例如open(FH, '-|', 'perl sort2.pl gettysburg.txt');
[*]管道:将当前程序的STDOUT输出接入下个程序的STDIN:open(SORT, '|-', command);例如open(SORT, '|-', 'perl sort2.pl');
[*]管道:可使用IPC::Open2建立双向管道(未详述)
[*]lc(str)将字符串str中字母转换为小写后输出,uc(str)则转换为大写
[*]类似shell的文件测试:(-operator $file),operator包括:

[*]e $file存在时为true
[*]f $file为文件(不是目录)时为true
[*]d $file为目录时为true
[*]z $file大小为0时为true
[*]s $file大小不为0时为true
[*]r $file可读时为true
[*]w $file可写时为true
[*]x $file可执行时为true
[*]o $file为当前用户拥有时为true

第9章:字符串处理

[*]length(str)返回str的长度
[*]index(str, substr)返回str中substr第一次出现时的下标,substr不存在时返回-1

[*]index(str, substr, mindex)指定从mindex开始查找

[*]rindex(str, substr)返回str中substr最后一次出现时的下标,不存在时返回-1

[*]rindex(str, substr, mindex)指定从mindex开始查找

[*]substr(string, starting_index, length)返回string中从starting_index开始取length长度的子串
[*]tr///用于字符替换,例如tr/old/new/将会建立如下字符替换规则:o->n, l->e, d->w,例如$string = ‘2011064’,而执行$string =~ tr/0123456789/abcdefghij/;或$string =~ tr/0-9/a-j/;后,$string变为‘cabbage’

[*]d修饰符用于删除字符,例如my $vowels = $string =~ tr/aeiou//;并不能删除$string中的元音字母,而my $vowels = $string =~ tr/aeiou//d;就可以。再例如$string =~ tr/ //d;可删除$string中的所有空格

第10章:OS交互
  

[*]%ENV保存了所有环境变量(改变%ENV并不能真正改变系统环境变量设置),例如$ENV{HOME},$ENV{PATH},$ENV{USER}等
[*]文件通配符:glob(pattern)函数用以返回下一个满足pattern的文件名,例如glob(‘*.pl’),等价于<*.pl>,表示所有扩展名为pl的文件。

while (glob('*.dat')) {
print "found a data file: $_\n";
}

[*]可以使用opendir打开一个目录,通过readdir函数读取其中包含的文件,closedir关闭:

opendir DH, "." or die "Couldn't open the current directory: $!";
while ($_ = readdir(DH)) { … }
closedir DH;

[*]以下函数与UNIX API相同或类似,可参照APUE(《UNIX环境高级编程》)


[*]chdir(directory)
[*]unlink(list_of_files) 可unlink多个文件




[*]rename(old_file_name, new_file_name)
[*]link(file_to_link_to, link_name)
[*]symlink(file_to_link_to, sym_link_name)
[*]readlink(sym_link_name)
[*]mkdir(directory_name, mode)
[*]rmdir(directory_name)
[*]chmod(file_or_directory_name, mode)
[*]system(command)


[*]system()函数将执行命令的输出打印至控制台(STDOUT),返回进程的执行结果(个人推断:main函数的返回值)。而使用`command`则可将输出捕获,例如:

[*]$output = `$command`;将$command执行的输出保存至字符串$output,包括换行符
[*]@output = `$command`;将$command执行的输出保存至列表@output,每行一个元素,包括换行符

页: [1]
查看完整版本: 《Beginning Perl》读书笔记3:6~10章