随手记一记学Perl 时容易搞混的地方
1. while 循环控制体中是布尔上下文,但是for 相应的部分是列表上下文。所以你用for 循环替换print while (<>);
时,得到的行为肯定不同。
2. kes 和values 会重置hash 的定位器,each 遍历完整个hash 之后也会重置定位器,不要在遍历的时候增加新的键值对。
3. 不要在keys 和values 调用之间增加键值对,否则keys 和values 难以匹配。
4. 函数调用可以省略括号,但是perl 的想法可能和你不一样,所以当你
print sort @something, "_something";时,得到的结果和print (sort @something), "_something";不一样。当然你写出print (1+2) * 3;这样的程序时,也不会得到⑨; 5. print 函数参数中列表的内插会导致在列表每一个元素的后面多带一个空格。
6. 一些特殊变量:http://blog.csdn.net/ispeller/article/details/8859517
7. 元字符不会匹配换行符。
8. 捡破烂模式(.*) 可以匹配任何字符串,所以/(abc)*/ 可以匹配"Hello world!",但是捡破烂模式不能匹配回车字符(当然/s 可以解决这个问题)。
9. Perl 中的注释也是一种空白,所以在正则表达式匹配的时候可以用/x 修饰符来在其中加入注释(注释中不要把定界符写进去)。
10. 正则中的一些常用符号:
【修饰符】
\i: 大小写无关匹配。
\s: 效果等同于[\d\D]。(包含换行符)
\x: 表达式中的空白无意义。
【锚位】
^: 锚位字符串开头,如果在字符集中则是反义。
$: 锚位字符串结尾(包含换行符)。
\b: 锚位单词边界。
【字符集简写】
[\d]: 。
[\w]: 。
[\s]: [ \f\t\n\r]。(有个空格)
[\h]: [ \t]。(有个空格)
[\v]: [\f\n\r]。
【量词】
* : {0, }
+ : {1, }
? : {0, 1},紧跟量词之后表示非贪婪。
11. 正则表达式中\n 和$n 的区别是:$n 是\n 的结果。$n 的生命周期可以持续到下一次成功的匹配。
12. (?<name>string) 可以进行命名捕获,结果进入哈希%+,其中name 可以用于反向引用\g{name} 或者\k<name>,而 (?:string) 则表示纯粹为了分组而存在的括号,不进行捕获。
13. \g{name} 和\k<name> 的区别是:\g{name} 可以实现相对反向引用。
14. 原匹配串 = $` + $& + $';这三个自动变量的生命周期也会持续到下一次成功匹配。
15. Split 会保留列表开头的空字段,但会舍弃列表结尾的空字段。Split 使用/\s+/ 作为默认模式,使用$_ 作为默认分隔对象。
16. m// 返回的是匹配成功的列表。
17. perl 段落运算符返回的是最后进行运算的表达式的值(这恰好就是整个短路运算的布尔值)。
18. 函数chomp 和chop 的作用不一样:
s/$//; # same as chomp
s/.$//; #same as chop
所以有时它们的行为一样只是巧合而已。
19. Perl 中赋值语句返回实际的变量作为左值,所以你可以使用
($scalar += 1) -= (1+2);
类似的赋值语句来多次改变变量的值。
20. 数组内插时,使用$" 指定的分隔符进行内插。
21. 命名一元操作符的优先级比二院操作符高,所以当你
sleep 3|4;时,会sleep 3 秒而不是7 秒。但是列表操作符比二元操作符优先级低,虽然刚才你只能sleep 3 秒,但是当你
print 3|4;
的时候你的确会在标准输出中看到7。
22. -A -C 和-M 返回的时间(脚本开始运行至今的天数,保存在$^T)大多数是一个分数,所以和一个整数做相等性比较的时候必须用int 函数转换
90 == int -A and &do_sth;
23. and 和 &&,or 和|| 的优先级是不一样的,前者的优先级比后者要远远来的低,甚至比= 还低,所以
$num = 1 || 2 || 3;和$num = 1 or 2 or 3;表达的意思完全不一样。
页:
[1]