之前对perl只是知道一点,对于它对正则表达式的强大处理也只是闻于耳。于是,愣是花了4天时间看了小骆驼,一天时间浏览了圣经大骆驼,对Perl的设计哲学颇为赞叹,只是在我们身旁它的推广度太低了,不过也只有用过它的人知道Perl的利端,作为入门者,也没有很多好说的,只是略微做了一些学习笔记:
encoding = utf-8
++ 变量前导符
+ $ 标量,@列表(数组),%(哈希表/散列),&(子过程),*(类型团,参看programming perl p101)
++ 操作符
+ 双目操作符 +,-,*,/,%,**(幂)
+ 字符串操作符 (字符串连接),x(字符串重复)
+ 赋值操作符 =,+=,*=,/=,**=,-=,.=,&=,|=,<<=,>>=,%=,&&=,||=,x=
+ 单目算数操作符 ++,--
+ 逻辑操作符 &&,||,!,and,or,not,xor(异或)
+ 比较操作符 针对数字: ==,!=,<,>,<=,>=,<=>(比较,用在高级sort)
针对字符串:eq,ne,lt,gt,le,ge,cmp(比较)
+ 文件测试操作符 -e -r -d -f ...参考文件操作的文件检验部分.
+ 引用操作符 箭头 -> (参看引用部分).
++ 双引号字符串中的转义字符
+ \n 换行.
+ \r 回车.
+ \t 制表符.
+ \f formfeed.
+ \\ 反斜杠.
+ \" 双引号.
+ \l 下个字符小写.
+ \L 接下来的字符均小写直到\E.
+ \u 下个字符大写.
+ \U 接下来的字符均大写直到\E.
+ \Q 在non-word字符前加\,直到\E.
+ \E 结束\L,\U,\Q.
+ \l \L \u \U \E在替换模式s///中依然有用.
++ 系统变量(更多的系统变量请参看perlvar)
+ $_ 循环体foreach默认控制变量, 行输入符<>的默认输入变量(当然输入的字符不会自动存储在$_,只有当行输入操作(<STDIN>)单独出现在while循环的条件判断体时).
如 foreach (@array) #打印列表array的所有元素
{
print $_;
}
+ @_ 保存子程序的参数列表.
+ $! 保存程序出错(系统拒绝请求)后传给die函数的具体出错原因.
+ $& 模式匹配中匹配上的字符串保存的地方.
+ $` 模式匹配中匹配部分的前一部分保存的地方.
+ $' 模式匹配中匹配部分的后一部分保存的地方.
+ $a $b 高级排序子程序中的系统变量, 参看程序13.3, 或learing perl p165-167.
+ $@ eval捕获的错误原因列表.
+ %ENV 保存系统变量的哈希表.
++ 行输入操作<>
+ 默认的文件列表来源于命令行的输入,保存在$ARGV中.
++ 六个Perl自身的文件句柄STDIN, STDOUT, STDERR, DATA, ARGV, ARGOUT.
+ STDIN 标准输入,键盘.
+ STDOUT 标准输出,屏幕.
+ STDERR 标准错误
+ DATA
+ ARGV 命令行的输入参数列表,如行输入符<>的默认参数(如文件名等)列表.
+ ARGOUT
++ 一些关键字
+ scalar 转换成标量.
+ keys 对哈希表的key操作.
+ values 对哈希表的value操作.
++ 函数(参看perlfunc)
+ chomp 去掉换行符.
+ reverse 调换所有的行.
+ print 打印.
+ printf 格式化输出.
+ pop 删除并返回列表最后一个元素.
+ shift 删除并返回列表第一个元素.
+ sort 按照ASCII大小排序.
+ open 打开文件(句柄),返回成功或失败.(参看ex7_regex)
+ select 选择print的输出句柄,print的默认输出句柄是STDOUT,屏幕.参数为句柄.
+ split 分割函数. @field = split/分割符/,$string.(参看9.1).默认时,split对$_操作,模式(分割符)为空白;
+ join 粘合函数.执行split函数相反的功能. $var = join $glue,@array 将列表array中的元素用分割符$glue连接起来放到变量$var中.(参看9.1)
+ die 结束程序,并按参数输出缘由.
+ warn 按参数输出警告,程序继续执行.
+ localtime 可读时间函数.
+ gmtime 世界形式时间函数.
+ time 调用系统时间函数.
++ 哈希表函数:(哈希表有时候很有用,参看ex6.1,10.2统计词频)
+ keys 参数为%哈希表,如果在标量上下文返回表的大小,如果在列表上下文返回表的所有keys.
+ values 参数同keys.如果在标量上下文返回表的大小,如果在列表上下文返回表的所有values.
+ each 返回key/value对.
+ exists 查看哈希表中是否存在某个元素.
+ delete 删除表中给定key值的元素和对应的value.
++ 引用
+ 引用 分硬引用和符号引用(和硬链接和符号链接类似).被引用的可以是标量,数组,哈希表,子过程...而引用创建后是一个标量.
+ \ 用反斜杠创建一个引用.
$scalarref = \$foo; $constref = \286_252.42; $arrayref = \@ARGV; $hashref = \%ENV; $coderef = \&handler; $globref = \*STDOUT;
+ [] 用中括号创建一个匿名数组引用(因为被引用的变量没有命名)
创建一个数组匿名引用 $arrayref = [1,2,['a','b','c','d']]; 那么$arrayref->[2][1]的值将为"b".
+ {} 用大括号创建一个匿名哈希表引用.
创建一个哈希表匿名引用
$hashref =
{"a"=>1,
"b"=>2,
"c"=>3,
};那么$hashref->{"a"}的值将为1.
创建一个数组哈希表引用
$studentref = {
"chaonin"=>[25,"m","cs"],
"xuqiaojuan"=>[24,"f","cs"],
"shengdonghui"=>[25,"m","ee"],
}; 那么$studentref->{"chaonin"}[2]的值为"cs".
...
+ 句柄引用.
+ 符号表引用.
+ 标量引用的使用 $$scalarref(上面的定义).
+ 列表引用的使用要用箭头->,当然也可以为$$arrayref[0](这是两种不同使用引用的方法) ...
++ 数据结构(参看programming perl第九章)
+ 数组的数组
+ 数组的散列
+ 散列的数组
+ 散列的散列
+ 函数的散列
++ regular expression正则表达式(learning perl7,8,9章介绍)(更多内容请参看perlre)
++ meta character元字符
+ . 匹配所有的单个字符,除了换行符"\n".
+ 要匹配某个元字符必须在之前加个反斜杠\.
+ 斜杠/不是元字符,当它不是分割符而又出现在模式中时前面不需要反斜杠\.
++ anchors锚定
+ ^ 表示在字符串的开头(或行首)进行匹配.
+ $ 表示在字符串的结尾(或行尾)进行匹配.
+ Perl中字符串可能含有多行(里头有字符\n),但正规表达式的^和$是匹配行首和行尾的,Perl中则是匹配字符串开头和结尾.因此如果字符串中有多行而又要匹配多行的行首和行尾,要用选项m:
/模式/m(表示mutiple lines多行).
++ 词锚定
+ \b 针对单词.比如/\bchaonin\b/将匹配独立的单词chaonin,不会匹配amchaonin或者chaoninGuo,当然amchaonin可由/chaonin\b/匹配到,而chaoninGuo可由/\bchaonin/匹配到.
+ \B 非词锚定.好比\b的取反.比如/chaonin\B/将匹配/chaonin\b/不会匹配到的点.
++ binding operator绑定符
+ =~ Perl默认对变量$_进行匹配,而=~将告诉Perl将右边的模式在左边的字符串上进行匹配,返回true或者false.
+ !~ 和=~类似,只不过是不匹配.
++ quantifier数量词
+ * 匹配前一项0次或多次.
+ + 匹配前一项一次或多次.
+ ? 前面一项要么出现要么不出现,即匹配前一项一次或者不匹配前一项.
+ general quantifier通用量词.一对大括号和里面的可选数字将锁定匹配字符的个数./a{5,15}/将匹配5到15中任意数量的a,/a{5,}/将匹配5个以上的a且没有上限,/a{5}/将严格匹配5个a.
+ 非贪婪的数量词, * + {} ?都是贪婪的匹配,他们将匹配尽量多的字符.而*?,+?,{}?,??是增量式的匹配.就是简单的在前面加个?(参看learing perl p115-116)
++ 模式中的分组
+ 模式中的分组用括号()来表示.这时每队括号对应一个变量,有时我们只是想用括号进行区分,而不要存在相应的变量中,可以使用?:来表示, /(?:a)(b)(c)/将把b和c的匹配赋给$1,$2,a对应部分不赋值.
++ 选择符|
+ | 表示匹配左边一项或右边一项.如/a|b/将匹配a或b.
++ character class字符类
+ [] 方括号中的所有字符组成了字符类,它能匹配括号内出现的任何字符,但只能匹配一个字符.
+ 一些字符类的简写 数字字符类[0-9]为\d (数字),单词字符类[A-Za-z0-9]为\w (word),空白字符类[\f\t\n\r]为\s (whitespace),
+ ^ 字符类的补集 [^\d]表示非数字,[^\w]表示非单词,[^\s]表示非空白符.可以分别用\D,\W,\S来表示.不要和代表行首的^混淆.
+ [\d\D]能匹配所有字符包括换行符,但.不能匹配换行符.
++ modifier修饰符,通常称为flag
+ i 大小写无关.如/yes/i 将匹配大些或小写的yes或者大小写夹杂的yes.
+ s 匹配任何单个字符,同[dD],弥补元字符.的缺陷.往往用来匹配那些在分部在不同行的部分.
+ x 允许你在模式中添加任何数量的空格.比如/-?\d+\.?\d*/可读性很差,那么你可以用/ -? \d+ \.? \d* /x 这下可读性要好多了.这时候模式中的空格
和制表符将被忽略,你可以在空格或制表符前加\,但匹配空白的方法一般用\s或\s*或\s+. Perl中的模式就可以有注释了(以#开头,空白结尾),如:
/ -? #可选的负号 \d+ #小数点前一位或多位数 \.? #可选的小数点 \d* #小数点后可选的数字 /x #模式结束 .
+ m 使模式可以匹配多行.
+ 可选符的结合 这些可选符可以同时使用,顺序没关系.
++ 模式中的内插
+ 在模式中也可以插入变量来动态地指定要匹配的字符串.(参看8.3)
++ match variables匹配变量
+ 在模式中添加括号(),一对括号对应一个变量,之后可以引用这些变量.这些变量的引用为$1,$2,$3....(也可以为\1,\2,\3...)要注意的是这些变量在内存中只保存到下次匹配成功之前,
所以判断匹配成功后要尽早引用这些变量.$1,$2,$3和\1,\2,\3的区别是前者在匹配成功才赋值,后者是在模式里分好组后就赋值了,因此后者在模式里用,而前者在模式匹配后用.比如/(a)\1(b)/将匹配aab,而/(a)$1(b)/就会出错.(参看程序11.1,不知道后者可否在匹配后用,11.1测试结果是不行.)
+ 自动匹配变量$&,$`,$'请参看系统变量部分.
++ 替换s///
+ s/a/b/ 把模式a匹配到的部分替换成b.替换成功返回true,失败返回false.
+ s/a/b/g 全局替换.而s/a/b/只替换第一次匹配到的部分.
+ s/a/b/i, s/a/b/s, s/a/b/x这些可选的修饰符还是和原来一样.
+ 绑定符=~对s///仍然有效, $var =~ s/a/b/g将替换变量var中的所有a为b.
++ 列表上下文的模式匹配
+ 如果要把匹配的结果保存到列表中,哈希表中,各个变量中,也是可以的.请参看中文版learning perl p114.
++ 字符替换符tr///(和模式匹配//,替换s///很像,但和正则表达式没关系,只不过它也可以用绑定符=~而已,所以在这里介绍)
+ tr/searchlist/replacelist/把searchlist的字符替换成replacelist的相应字符,返回替换的字符数或删除的字符数.replacement为空的,searchlist替换为自身.
+ 它也有选项 c 把searchlist取补 d删除找到的但没有替换的字符 s消除searlist重复的字符.
如: tr/aeiou/!/ 把元音字符替换为!
tr{/\\\n\r\b\f}{_} 把怪异字符替换为下划线
$count = ($para =~ tr/\n//) 计算$para里的换行数
$count = tr/0-9// 计算$_里的位数($_是数字的话)
$word =~ tr/a-zA-Z//s; $word = bookkeeper,那么$word = bokeper
++ 控制结构
+ if(){}else{}.
+ unless(){}else{}.
+ while(){}.
+ until(){}.
+ if(){}elsif(){}elsif(){}...else{}.
+ for(){} 和c一样.
+ 自增/自减 ++ -- 和c一样.
+ 对于只有单个表达式的语句,可以把括号和大括号省略并把条件/循环放到最后,如:
print "$n is a negative number.\n" if $n < 0; #...
print "\t",($n+=2) while $n < 10; #...
print $_ foreach @person; #打印列表person的每个元素
...
+ Perl的5种循环体分别是for,foreach,while,until和裸块(是的,裸块也是循环体.但大括号括起来的if块和子程序都不是循环体).
+ last 从循环体里跳出,类似于c里的break(只对上面提到的5个循环体有效).
+ next 进行下轮循环,类似于c里的continue.
+ redo 重新进行改轮循环,c里没有这种控制符.
+ 标签块 Perl中的标签只能在整块之前使用,而不能像c一样放在代码的任何地方.标签可以和last,next,redo配合使用.
+ && || 逻辑与/逻辑或,可以用and/or表示.
如:人们更愿意对打开文件进行如下操作,
open FILE,$filename or die "Can't open '$filename':$!";
+ ! 逻辑非,可以用not表示.
+ ?: 三元操作符和c一样.
++ 位操作
+ & | ^ ~ << >> 与 或 异或 非 左移 右移.
++ 文件操作
+ open FILE,"> $filename" 写打开文件,返回true或false,成功时文件句柄保存在FILE中;
+ open FILE,"< $filename" 读打开文件,返回true或false,成功时文件句柄保存在FILE中;
+ open FILE,">> $filename" 追加打开文件,返回true或false,成功时文件句柄保存在FILE中.
+ open FILE,"<(或者>,>>)",$filename 三参数类型open,避免<,>和>>与文件名混淆.
+ close FILE 关闭文件句柄.
+ < 读文件 只要使用行输入符<>,中间加句柄就行了: <INFILE>.
+ >和>> 写文件 print OUTFILE "something to output";句柄后不用逗号.
或 printf OUTFILE "...%fomat something to output",$var;格式化输出,格式化串和输出变量之间有逗号.
++ 文件检验 文件检验有很多选项(具体参看learning perl page 140)(这些对于文件权限的判断,目录和文件的访问,访问和修改时间,文件类型的判断很有用.)
+ -f -d -l -S -p -b -c 检测文件类型.
+ -M -A -C 检测文件修改访问时间.
+ -T -B 检测文件是文本还是二进制.
+ -t 检验是不是TTY.
+ -r -w -x -R -W -X 检验文件的权限.
+ -s ...还很多,查看书吧.
+ stat函数 查看文件的状态.
+ 以上选项或函数的参数可以是文件名或文件句柄,视情况而定.
++ 目录操作
+ chdir 改变工作目录. chdir "/etc" 将转换工作目录到/etc.
+ glob 取得当前目录下某类文件的文件名.和chdir配合使用可以检测任意目录下某类文件的文件名. @file_c = glob "*.c"取得当前目录下所有c文件.glob可以用<>替换,但最好不要因为很容易和文件句柄输入符冲突.
+ link $a,$b 将$b链接到文件$a,这是硬链接,即完全拷贝.文件$a的inode的连接数会增1.
+ symlink $a,$b 同上,只不过是符号链接.文件$a的inode的连接数不变.
+ readlink 读取链接目标. $var = readlink $b.
+ link和symlink的更多区别参看learning perl p153-157.
+ unlink 删除文件(来源于删除链接link).参数是文件名列表.返回值为成功删除的文件数.而glob的返回也是文件名列表,因此可以和glob结合使用.(和文件链接没关系哦)
如 unlink glob "*.o" 将删除当前目录的所有.o文件.
unlink "file1","file2" 将删除文件file1和file2.
+ rename 文件重命名.rename "file1","file2" 将把file1命名为file2.成功返回true,否则为false.这对于要成批的修改文件名很有用.(参看程序12.1)
+ mkdir 以下参看learning perl157
+ rmdir
+ chown
+ utime
++ 目录句柄(参看learning perl p148-151)
+ opendir 打开目录句柄,和open类似.
+ readdir 读目录句柄,取得文件名.
+ closedir 关闭目录句柄.
++ 字符串
+ substr $sub = substr($string,$beginpos,$length)返回$string从beginpos(0为起始)开始长度为length的子串.如果省略第3个参数,那么返回开始位置到结尾.还可以对相应位置的子串进行修改: $string = "guo chaonin",substr($string,4) = "chaonian"后$string为"guo chaonian".还可以和绑定符 =~ 一起结合用,参看learning perl p163.
+ sprintf sprintf参数和printf的参数完全相同(除了可选的文件句柄外),不要被迷惑了,它返回处理后的字符串而不是打印.更具体的参看learning perl p163-165.(对时间和大数字的打印很有效,参看13.2)
++ 高级排序
+ 三向符<=>和cmp,前者针对数字后者针对字符串(字符串时别忘了加双引号).
+ 数字排序 参看程序13.3.
+ 哈希表排序 对哈希表的数字型/字符型(分别用三向符<=>和cmp)values进行排序,参看程序13.4.当然还可以对多个关键字进行排序,参看程序ex13.1.
++ 进程管理
+ system 调用系统函数.
+ exec 调用系统函数,和system的区别是system是创建一新进程,而exec不创建新进程. 更多参看learning perl p171-174.
+ open 同步执行...
+ fork 创建子进程...
+ kill 信号...
++ 模块
+ ...
++ 一些高级的技术
+ eval 捕获错误.对调试(别人的)代码很有用.eval是一个带大括号的表达式,不是程序块,因此括号后要分号.如果括号内的代码没有错误返回true,否则返回false.错误原因被放在系统变量$@ 中.
eval{code;};
eval有四种错误不能捕获:严重的程序错误,语法错误,exit退出(die则不会),-w选项的warnings.
+ grep ...
+ map ...
++ note
+ print @array和print "@array\n"是不同的,第二个是内插,会添加空格!
+ 在Perl中,和=>是等价的.
+ 在双引号里整个列表可以内插,而哈希表只能内插其中的一个元素不能内插整个哈希表.
+ 裸块中带有my的变量只在该块内可见,如:(裸块是指带大括号但没有条件的语句块)
{
my $var = 1; print $var;
}
$var在大括号外就消亡了.
+ Perl是一种结构化的语言.
+ Perl中对没有初始化的变量一般都自动初始化为0.
+ Perl被设计成90%处理文本,10%处理其余问题.
+ Perl设计哲学之一: there's more than one way to do it.
+ CPAN 全面Perl归档网络(Comprehensive Perl Archive Network)
可以看到正则表达式的东西确实很多,而这里只是杂碎的东西不足挂次。