Perl笔记


注释

=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:$val\n";
 }


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,4,5,6,7,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, $p2\n";   #输出 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, $p2\n"; #输出 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 "123456789\n";
    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 表示 [\f\t\n\r]  #空白字符(whitespace), 由格式符(form-feed), 制表符(tab), 换行符(next), 回车符(return)。


字符类的补集

\D 表示[^\d] #非数字

\W 表示[^\w]

\S 表示[^\s] #非空白字符

[\d\D] 表示匹配所有的字符 的一种通用表示法


使用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"和“fred\n”。 在这里不关心换行符

\b 词界锚定。 /\bfred\b/ 能匹配fred,但不匹配frederick,alfred

\B 非词界锚定。 /\bsearch\B/,能匹配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", "abc", "123" 这5个字符串。
}

$string = join $glue @pieces;

sub test9{
	my @fields = ("", "home", "media", "abc", "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 在导入模块时需要搜索的目录列表




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值