注释
=pod
1.xxx
2.ddd
3.这是多行注释
=cut
#this is comment 单行注释
?
循环语句
while
$i = 1;
while($i < 10){
print $i."n";
$i += 1;
}
while ... continue...
my $i = 1;
while($i < 5) {
say $i;
} continue {
$i++;
}
until
my $i = 1;
until($i >=5 ) {
say $i;
$i++;
}
while(condition)? ==? until(! condition)
do ... while ...
my @a = (1 .. 10);
my $i;
do {
$i = shift @a;
say $i;
} while ($i < 5);
Perl 中没有 do 。。。while。。。循环语句, 实际上这是do语句与while语句一起工作。
for
for($i=1; $i<=9; $i++){
for($j=1; $j<=$i; $j++){
print "$j*$i=".($i*$j)."t";
}
print "n";
}
foreach
@list = (1 .. 5);
foreach my $i(@list){
print $i."n";
}
foreach (@list){
print "$_n";
}
each
my %array = (
"a" => "1","b" => 2,"c" => 3,);
while(my($index,$val) = each(%array)){
print "$index:$valn";
}
if ... elsif ... else
my @array = (1..10);
foreach (@array){
if($_ == 1) {
print "This is one($_)n";
}elsif($_ == 2){
print "This is two($_)n";
}else{
print "$_n";
}
if($_ > 5){
last;
}
}
unless ... else ...
my $i = 1;
unless($i > 5){
say "$i is not larger than 5";
}else {
say "$i is larger than 5";
}
if(condition)? ==? unless(! condition)
grep And map
my @UpCase = ("A" .. "Z");
say join('_',map lc,@UpCase);
say join('_',map chr,(65 .. 90));
say join(',',(grep {$_ > 15} (10 .. 20)));
执行结果如下:
a_b_c_d_e_f_g_h_i_j_k_l_m_n_o_p_q_r_s_t_u_v_w_x_y_z
A_B_C_D_E_F_G_H_I_J_K_L_M_N_O_P_Q_R_S_T_U_V_W_X_Y_Z
16,17,18,19,20
@_? all params list
$maximum = &max(3,5,10,7,4,2);
sub max{
my $max_val = shift @_;
foreach(@_){
if($max_val < $_){
$max_val = $_;
}
}
return $max_val;
}
print $maximum;
Array
@array = (1,2,3,6,8,9);
for $num(@array){
$num % 2 && print $num."t";
}
@array2 = (1..10);
print $array2[$#array2];
my $fred = "abcd";
my @fred = undef;
$fred[0] = "0";
$fred[1] = "1";
$fred[9] = "9";
print $fred[1];
my $a;
my $b;
my $c;
?? ?
($a,$b,$c) = (1,"abc",undef);
print $a;
#交换2个变量的值
($a,$b) = ($b,$a);
print $b;
??? my @x = (1..10);
?? ?my @y = @x; #将数组x 复制到 数组y
?? ?
?? ?@y[0] = 5;
?? ?print $x[0]; #还是1
??? my @temp = (1..10);
?? ?my $p1? = pop(@temp);
?? ?my $p2? = pop(@temp);
?? ?print "$p1,$p2n"; #输出 10,9
?? ?print "@temp"; #输入 1 2 3 4 5 6 7 8
?? ?print "n";
?? ?
?? ?push(@temp,'a');
?? ?push(@temp,'b');
?? ?print "@temp"; #输出 1 2 3 4 5 6 7 8 a b
??? $p1 = shift(@temp);?? ?
?? ?$p2 = shift(@temp);
?? ?print "$p1,$p2n"; #输出 1,2
?? ?print "@temp"; #输出 3 4 5 6 7 8 a b
?? ?print "n";
??? unshift(@temp,'y');
?? ?unshift(@temp,'x');
?? ?print "@temp"; #输出 x y 3 4 5 6 7 8 a b
?? ?print "n";
??? my @strs = qw(a b c d e f);
?? ?my @removed = splice(@strs,2);
?? ?print @removed; #输出 cdef
?? ?print "n";
?? ?print @strs; #输出 ab
$_ :? each param
for(@array){
print $_."t";
}
<pre name="code" class="plain">$_ = "aaa";
print; #输出aaa
qw (quoted,word 加上引号的单词,用空白圈引)
my @s = qw(a b c d e f);
for $i(@s){
print $i."t";
}
my @b = qw {
?? ??? ?/sbin
?? ??? ?/usr/sbin
?? ??? ?/usr/local/sbin
?? ?};
print $b[0];
Hash
#my %map = ("dog","1","cat","2","fish","3");
my %map = (
"dog" => '1',"cat" => '2',"fish" => '3'
);
print $map{'dog'};
my @animals = keys %map;
foreach my $i(@animals){
print $i;
}
my @number = values %map;
foreach my $n(@number){
print $n;
}
while(my($k,$v) = each(%map)){
?? ?say $k.'-->'.$v;
}
#以key排序
foreach my $k (sort keys %h){
?? ?say $k;
}
my $variables = {
??? "apple" => {
??????? "A" => 1,??????? "B" => 2,??? },?
??? "banana" => {
??????? "X" => 24,??????? "Y" => 25,?
};
print $variables->{"apple"}->{"A"};
文件操作
#!/usr/bin/env perl
use 5.010;
sub readFile{
?? ?my ($filepath) = @_;
?? ?say $filepath;
?? ?open FH,"<$filepath";
?? ?my @mytext = <FH>;
?? ?foreach my $text(@mytext){
?? ??? ?#say $text;
?? ??? ?my @line = split(":",$text);
?? ??? ?say $line[0];
?? ?}
?? ?close FH;
}
$filepath = "passwd";
&readFile($filepath);
第二种
open my $f,"<","f1.pl" or die "can not open $!";
while(<$f>){
?? ?print $_;
}
close $f;
写文件
sub f1 {
??? open(F,">a.txt") or die "can't open $!";
?? ?
??? print F "123456789n";
??? close F;
}
正则表达式
元字符
元字符,点(.)是通配符,匹配任何单个字符,但不包括换行符("n")。如果要匹配(.) 则需要.
量词
? 出现0或1次
* 出现0或多次
+ 至少出现1次
/fe+d/? 能匹配fed, feed
/go*d/ 能匹配gd,god, good, goood
/wo?d/ 能匹配wod, wd
分组
分组用括号()来表示, /(fred)+/ 能匹配 fredfred,fred 这样的字符串
选择符
用竖线(|)来表示,匹配左边或者右边。 /fred|barney|barney/,匹配出现fred,或者barney,或者betty的字符串。
字符类
字符类,是方括号[]中的一列字符,匹配括号内任意单个字符。
d 表示 [0-9] #digit
w 表示? [A-Za-z0-9_]? #word
s 表示 [ftnr]? #空白字符(whitespace),由格式符(form-feed),制表符(tab),换行符(next),回车符(return)。
字符类的补集
D 表示[^d] #非数字
W 表示[^w]
S 表示[^s] #非空白字符
[dD] 表示匹配所有的字符 的一种通用表示法
使用m//匹配
模式放在正斜线(//)里,这是m// 的一种简写。如果要匹配的字符串中有//,我们可以用m{}, m##,m%%来代替。
如果匹配http://www.google.com, m#http://#,m{http://},%http://%
可选修饰符
不区分大小写: /i
/yes/i 能匹配YeS
匹配任何字符:/s
点(.) 不匹配换行符,加上/s后,能匹配换行符。
添加空格: /x
/-?d+.?d*/? #不方便阅读
/-?? d+? .?? d* /x? #要好一点,这里的空白被忽略。
锚定
^表示开头进行匹配
$表示结尾进行匹配
/^fred$/,能同时匹配 "fred"和“fredn”。 在这里不关心换行符
b 词界锚定。 /bfredb/ 能匹配fred,但不匹配frederick,alfred
B 非词界锚定。 /bsearchB/,能匹配searches,searching,但不匹配search,researching。
绑定操作符 =~
$_ =~ /^s$/;
sub test1{
$_ = "yabba abc ff";
if(/abc/){
say ""/abc/" match "$_""; #显示 "/abc/" match "yabba abc ff"
}
if(/abc|ff/){
say ""/abc|ff/" match "$_""; #显示 "/abc|ff/" match "yabba abc ff"
}
if(m(abc)){
say ""m(abc)" match "$_""; #显示 "m(abc)" match "yabba abc ff"
}
}
sub test2{
my $t = "123abc456xyz";
if(${t} =~ /^d+ w+ d+ w+$/x){
say "it matched!"; #能匹配
}else{
say "it does not match!";
}
}
若匹配成功 则 $&:匹配的字符串, $`: 匹配字符串之前的字符串, $': 匹配字符串之后的字符串
sub test3{
my $t = "hello world,nice to meet you!";
if($t =~ /S(w+),/){
say "$&: $&"; #显示 $&: world,say "$`: $`"; #显示 $`: hello
say "$': $'"; #显示 $':? nice to meet you!
}
}
s/abc/xyz/? 来进行替换
sub test4{
$_ = "fred flintstone";
if(s/fred/wilma/){
say "true"; #能匹配上,显示true
}
say $_; #显示 wilma flintstone
}
sub test5{
$_ = "a b c d e f";
if(s/s+/ /g){ #把空白字符替换成一个空格
say $_; #显示 a b c d e f
}
say $_;
}
sub test6{
$_ = "http://www.baidu.com";
if(s#http://#ftp://#){
say $_; #显示 ftp://www.baidu.com
}
}
?U 转换成大写, L 转换成小写? $a=~模式
sub test7{
$_ = "/home/media/abc";
if ($_ =~s/(media|abc)/U$1/gi){
say $_; #显示 /home/MEDIA/ABC
}
if ($_ =~s/(abc)/L$1/ig){
say $_; #显示 /home/MEDIA/abc
}
}
@fileds = split /separtor/,$string;
sub test8{
my $string = "/home/media/abc/123";
my @fields = split ///,$string;
foreach (@fields){
say $_;
};
#显示输出"","home","media","123" 这5个字符串。
}
$string = join $glue @pieces;
sub test9{
my @fields = ("","123");
my $string = join "/",@fields;
print $string; #输出 /home/media/abc/123
}
这不是正则表达式,这个是glob
sub test10{
my @fs = glob "*.pl";
foreach(@fs){
say "$_";
}
# 显示 1.pl, 2.pl, 3.pl
}
多线程
#!/usr/bin/env perl
use warnings;
use strict;
use threads;
use 5.010;
sub f1{
my $num = shift;
say "thread: $num started";
sleep $num;
say "done with thread $num";
return $num;
}
sub main {
my @threads;
for(my $i=1; $i<=5; $i++){
my $t = threads->new(&;f1,$i);
push(@threads,$t);
}
foreach(@threads){
my $num = $_->join;
say "done with $num";
}
}
main();
#######显示结果#########
thread: 1 started
thread: 2 started
thread: 3 started
thread: 4 started
thread: 5 started
done with thread 1
done with 1
done with thread 2
done with 2
done with thread 3
done with 3
done with thread 4
done with 4
done with thread 5
done with 5
########################
多进程
#!/usr/bin/env perl
use warnings;
use strict;
use 5.010;
sub f1 {
my $num = shift;
say "child process $num started";
sleep $num;
say "done with child process $num";
return $num;
}
sub main {
my @childs;
for(my $i=1; $i<=5; $i++){
my $pid = fork();
if($pid){ # 父进程 pid是子进程ID
push(@childs,$pid);
}elsif($pid == 0){ # 子进程
f1($i);
exit 0;
}else{
die "couldn't fork:$!n";
}
}
foreach(@childs){
my $tmp = waitpid($_,0);
say "done with pid $tmp";
}
}
main();
#######显示效果########
child process 1 started
child process 2 started
child process 3 started
child process 4 started
child process 5 started
done with child process 1
done with pid -10708
done with child process 2
done with pid -10900
done with child process 3
done with pid -11256
done with child process 4
done with pid -9768
done with child process 5
done with pid -10792
#######################
Module
tool/MyModule.pm
#!/usr/bin/env perl
package MyModule;
require Exporter;
@ISA = qw(Exporter);
@EXPORT = qw(myFun1,myFun2);
@EXPORT_OK = qw($myVar1,$myVar2);
use strict;
use warnings;
our $myVar1 = 9;
our $myVar2 = 1;
sub myFun1 {
my $N = $myVar1;
foreach my $i (1..$N) {
foreach my $j (1..$i) {
printf("%d x %d = %2d ",$j,$i,$i*$j);
}
print "n";
}
}
sub myFun2 {
print ++$myVar2."n";
}
1;
main.pl
#!/usr/bin/env perl
use strict;
use warnings;
use 5.010;
use tool::MyModule;
sub main {
say "var1:",$MyModule::myVar1;
say "=" x 80;
$MyModule::myVar1= 5;
MyModule::myFun1();
$MyModule::myVar1= 8;
say "=" x 80;
MyModule->myFun1();
MyModule::myFun2();
MyModule->myFun2();
}
main();
OOP
Person.pm
#!/usr/bin/env perl
package Person;
use strict;
use warnings;
use 5.010;
sub new {
my $class = shift;
say("class=$class");
my $this = {};
$this->{'name'} = shift;
$this->{'age'} = shift;
bless $this,$class;
return $this;
}
sub getName {
my($this) = @_;
return $this->{'name'};
}
sub setName {
my($this,$name) = @_;
$this->{'name'} = $name;
}
sub getAge {
my($this) = @_;
return $this->{'name'};
}
sub setAge {
my($this,$age) = @_;
$this->{'age'} = $age;
}
sub toString {
my($this) = @_;
say "Hello my name is $this->{'name'},I am $this->{'age'} years old!";
}
1;
main.pl
#!/usr/bin/env perl
use strict;
use warnings;
use 5.010;
use Person;
sub main {
my $p1 = Person->new("Tom",24);
$p1->toString();
my $p3 = new Person("Jerry",25);
$p3->toString();
my $p2 = Person::new('Person',"cooper",28);
$p2->toString();
}
main();
Perl内部变量
$- 当前页可打印的行数,属于Perl格式系统的一部分
$! 根据上下文内容返回错误号或者错误串
$” 列表分隔符
$# 打印数字时默认的数字输出格式
$$ Perl解释器的进程ID
$% 当前输出通道的当前页号
$& 与上个格式匹配的字符串
$( 当前进程的组ID
$) 当前进程的有效组ID
$* 设置1表示处理多行格式.现在多以/s和/m修饰符取代之.
$,当前输出字段分隔符
$. 上次阅读的文件的当前输入行号
$/ 当前输入记录分隔符,默认情况是新行
$: 字符设置,此后的字符串将被分开,以填充连续的字段.
$; 在仿真多维数组时使用的分隔符.
$? 返回上一个外部命令的状态
$@ Perl解释器从eval语句返回的错误消息
$[ 数组中第一个元素的索引号
$ 当前输出记录的分隔符
$] Perl解释器的子版本号
$^ 当前通道最上面的页面输出格式名字
$^A 打印前用于保存格式化数据的变量
$^D调试标志的值
$^E在非UNIX环境中的操作系统扩展错误信息
$^F最大的文件捆述符数值
$^H由编译器激活的语法检查状态
$^I内置控制编辑器的值
$^L发送到输出通道的走纸换页符
$^M备用内存池的大小
$^O操作系统名
$^P指定当前调试值的内部变量
$^R正则表达式块的上次求值结果
$^S当前解释器状态
$^T从新世纪开始算起,脚步本以秒计算的开始运行的时间
$^W警告开关的当前值
$^X Perl二进制可执行代码的名字
$_ 默认的输入/输出和格式匹配空间
$| 控制对当前选择的输出文件句柄的缓冲
$~ 当前报告格式的名字
$` 在上个格式匹配信息前的字符串
$’ 在上个格式匹配信息后的字符串
$+ 与上个正则表达式搜索格式匹配的最后一个括号
$< 当前执行解释器的用户的真实ID
$<digits>含有与上个匹配正则表达式对应括号结果
$= 当前页面可打印行的数目
$> 当前进程的有效用户ID
包含正在执行的脚本的文件名
$ ARGV 从默认的文件句柄中读取时的当前文件名
%ENV 环境变量列表
%INC 通过do或require包含的文件列表
%SIG 信号列表及其处理方式
@_ 传给子程序的参数列表
@ARGV 传给脚本的命令行参数列表
@INC 在导入模块时需要搜索的目录列表