ITPub博客

首页 > Linux操作系统 > Linux操作系统 > perl学习笔记1

perl学习笔记1

原创 Linux操作系统 作者:myownstars 时间:2011-07-27 17:04:30 0 删除 编辑
如何debug一个perl程序
--5.6版本或更高,
#!/user/bin/perl –w
Use warnings;--此时会报告编译错误,但不会终止程序运行
Use diagnostics;--查看更详细的诊断说明,但程序会启动很慢(向内存中加载警告和详细说明)

$ perl –M diagnostics ./my_program—避免每次都加载内存,比较方便,直接显示错误信息


单引号与双引号的区别
单引号—除了单引号和反斜线字符,所有字符都代表自己;标示反斜线字符本身,需要在其前面再加一个反斜线;
‘hello world\n’—输出hello world\n
'hello'\\n'—会报错Backslash found where operator expected at test.pl line 1, near "'hello'\"
print 'hello\'\\n' –输出hello'\n
双引号
--\代表转义字符
“hello world\n”—输出hello world,后面紧接换行符

如何连接字符串
采用’.’--”hello ”.”world”等同于”hello world”
“justin” X 3—等同于”justinjustinjustin”


获取用户输入
--,获取用户行输入,会等待
$line = ;
If ($line eq “\n”) –用户输入换行符,

Chomp
--去除行尾的换行符
Chomp($text = )等同于 $text =; chomp($text);

Qw
--建立字符串列表,不必输入引号;
Qw( fred barney betty dino )也可以qw< a b c >或qw# qa qb qc #
($a[0], $a[1], $a[2], $a[3]) = qw/a b c d/;
@a = qw/ a b c d /;

POP/PUSH操作符
@array = 5..9;
$a = pop(@array);--@array为(5,6,7,8),$a为9
Pop @array;--@array现在是(5,6,7)
Push(@array,0)--@array现在是(5,6,0)

Shift/unshift操作符
@a = qw# dino fred barney #;
$m = shift(@a);--$m为dino,@a为(“fred”,”barney”)
Unshift(@a, ‘asd’);--@a现在为(“asd”,”fred”,”barney”)

字符串数组内插
@a = qw( a b c);
$email = “fred@a.edu”—则会内插@a数组
应写为
$email = “fred\@a.edu”或者$email = ‘fred@a.edu’;

Foreach控制结构
@rocks = qw/ bed slate lava /;
Foreach $rock (@rocks) {
 $rock = “\t$rock”;
 $rock .= “\n”;
}
循环结束后,控制变量会恢复成循环执行之前的值

$_ “老地方” 默认变量
--当未告知perl使用哪个变量视,自动使用$_
Foreach (1..10) {
  Print “ I can count to $_ \n”;
}

$_ = “Yahoo \n”;
Print;--默认打印$_

Reverse
--读取列表的值,并按相反的次序返回该列表
@a = 6..10;
@a = reverse @a;-- 此时a的值10,9,8,7.6
Reverse @a;-- 语法错误


Sort
--读取列表的值,并且根据内部的字符编码的顺序,进行排序;对ASCII编码的字符串,则按ASCII码排序
@rocks = qw/ a b c d /;
@rocks = sort @rocks; --排序后为a b c d


标量上下文/列表上下文
--列表上下文产生元素的列表;标量上下文则会返回数组中元素的个数
@a = qw( d z a );
@b = sort @a;--列表上下文a,d,z
$n = 42 + @a;--标量上下文:42 + 3,得45
@backward = reverse qw / a d c/--变成a,c,d
$backward = reverse qw / a d c/--变成cda,标量上下文
$fred = somethind;--列表上下文
($fred) = somethind;--标量上下文

清空数组
@betty = ( );
@betty = undef;--得到一个列表,且仅有一个元素;清空失败

强制指定标量上下文
--在列表上下文的地方,强制引入标量上下文,可以使用伪函数scalar
@rocks = qw( a b c d );
Print “ I have “, @rocks,” rocks \n”;--输出各种石头的名称
Print “ I have “, scalar @rocks, “ rocks \n”;--输出石头的数量

列表上下文中的
--标量上下文中返回输入数据的下一行;列表上下文中返回所有剩下的行,直到文件结尾,从键盘输入的按control-D标示文件结尾;
@lines = ;--列表上下文读取标准输入
Chomp(@lines);--
Chomp(@lines = );--读入所有行,且去除换行符

一次读入的是400M的日志文件,perl会全部读入,会占用至少1G的内存,因为perl通常浪费内存来节省时间;



子程序
--使用sub定义,可以在程序的任何地方
--可以在任意表达式中使用子程序名,用&调用
--子程序最后一次运算的结果会被自动当成返回值
$n = &max(10.15);
参数列表被传入子程序,数组变量为@_,在子程序执行期间有效;子程序的第一个参数存储于$_[0],第二个为$_[1];
--私有变量
Sub max {
  My($m,$n);--私有变量
  ($m,$n) = @_;
  If ($m > $n) {$m} else {$n}
}
--限制长度可变的参数列表
Sub max{
  If (@_ != 2) {
Print “ &max should get exactly 2 arguments \n”;
  }
}
--更好的&max子程序
--采用high-water mark算法
$maximum = &max(3,5,10,6,4);
Sub max {
  My($max_so_far) = shift @_;--将数组中的第一个值,暂时当做最大值
  Foreach (@_) {--遍历数组中的其他元素
If ($_ > $max_so_far) {
  $max_so_far = $_;
}
  }
$max_so_far;
}
非标量返回值,可以返回列表值
--想取出某段范围的数字
Sub list_from_fred_to_barney {
  If ($fred < $barney) {
$fred..$barney;
  } else {
  #从$fred倒数回$barney
  Reverse $barney..$fred;
  }
}
$fred = 11;
$barney = 6;
@c = &list_from_fred_to_barney;--@c的值为(11,10,9,8,7,6)

持有性私有变量
--使用state声明变量,子程序可以多次保留变量
--任意类型的变量都可以被声明为state变量
Sub marine {
  State $n = 0;
  $n += 1;
  Print “Hello, sailor number $n \n”
}

Running_sum(5,6);
Running_sum(1..3);
Sub running_sum {
  State $sum = 0;
  State @numbers;
 
  Foreach my $number (@_) {
Push @numbers, $number;
$sum += $number;
  }
 
 Say “The sum of (@numbers) is $sum”;
}
输出
The sum of (5,6) is 11;


标准输入
--作为行输入,读取到文件结尾,会返回undef,自然会跳出循环
--while (defined($line =)) { print “I saw $line”;};
钻石操作符<>
--行输入操作符特例,
--while (defined($line = <>)) { ….};
调用程序./my_program fred betty,则会依次读入文件fred/betty中的内容;切换文件时候中间不会有间断;
--<>的参数来自@ARGV数组,由perl解释器建立的,与普通数组使用一样;
--调用参数



标准输出
Print @array;--一个接一个的打印出数据中元素,之间没有空格
Print “@array”;--打印字符串,以空格间隔
Print (2+3)*4;--输出5;接着perl从print取得返回值1,再将它乘以4;

格式化输出printf
%g—按需要自动选择浮点数、整数或指数
%d—显示整数,舍掉小数点
%s—字符串;printf “%10s\n”, “Wilma”输出     Wilma;
%%--输出百分号;printf “%.2f%%”;输出0.00%
输出数组
my @item = qw { justin abc  dbc asdg };
printf "The itme are:\n".("%10s\n" x @item),@item;
输出—括号中的@item是标量上下文,而后面的是列表上下文
The itme are:
     justin
       abc
       dbc
      asdg

文件句柄
--程序里代表perl与外界之间I/O联系的名字,建议名字全部大写
--6个保留名:STDIN、STDOUT、STDERR、DATA、ARGV、ARGVOUT
./my_program Wilma—程序的输入文件来自文件dino,输出到文件wilma
Cat fred barney | sort | ./my_program | grep something |lpr
--将文件fred和barney中的内容输出并排序,然后输入到perl程序,运行完再过滤出需要的结果并发送到打印机打印

打开文件句柄
Open CONFIG, “dino”;
Open CONFIG, “Open CONFIG, “>dino”;--打开文件并向其写入信息,写之前清空原有信息
Open CONFIG,”>>dino”;--打开文件并向其追加信息
可以使用任何的标量表达式
My $file = “my_output”;
Open LOG, “> $file”;--中间有空格,避免文件名中出现’>’,导致>变成>>;
不正确的文件句柄
My $success = open LOG, “>>logfile”;
If (! $success){ ..open操作失败}

用die处理严重错误
--当程序遭遇到严重错误时,die函数会输出指定的信息到标准错误流中,并让程序立即终止,并返回不为0的退出码;
If (! Open LOG, “>>logfile”) {
  Die “Cannnot create logfile:$!”;--$!是可读的系统出错信息
}

使用warn输出警告信息
--功能与die类似,但不会终止程序运行

改变默认的文件输出句柄
--不显示指定,默认输出到STDOUT
Select BEDROCK;--接下来的print/printf将向BEDROCK句柄中输出信息
--数据输出到文件句柄时,默认都会经过缓冲处理;$| = 1;#立即刷新缓冲区

复用标准文件句柄
--打开已经被打开过的文件句柄,包括6个标准文件句柄
--open STDERR, “>> /home/oracle/.error_log”

Say
--等同于print,但行尾自动加上换行符
--输出内插数组,仍需要用引号括起来,否则数组中的元素会连成字符串
My @array = qw( a b c d);
Say @array;--输出abcd\n
Say “@array”;--输出a b c d\n


哈希
--$hash($some_key);赋值$family_name(“fred”) = “bac”; $file = $family_name(“fred”);不存在的值会得到undef;
--%访问整个hash;
%some_hash = (“foo”,35,”bar”,2.5); 也可使用直观的胖箭头 my %last_name = ( “fred” => “flintstone”, “dino” => undef);
--赋值给数组 @array = %some_hash;但是排列顺序可能会变
--%new_hash = %old_hash;%inverse_hash = reverse %any_hash发转hash

Keys/values函数
--my %hash =(“a” => 1,”b” => 2,”c”=> 3);
--my @k = keys %hash;--a,b,c
--my @v = values %hash;--1,2,3
--在标量上下文中,这两个函数都会返回哈希中键/值对的个数,计算过程不必对整个哈希进行遍历
My $count = keys %hash;--得到3

Each函数
--罗列哈希的每个键/值对
While ( ($key,$value) = each %hash ) {
  Print “$key => $value\n”;
}
--each返回键/值的顺序是乱的,如果需要依次处理哈希,对键排序
Foreach $key ( sort key %hash ) {
  $value = $hash($key);
  Print “$key => $value\n”;或者print “$key => $hash($key)\n”;
}

Exists函数
--检查哈希中是否有某个键
If ( exists $books(“justin”) ) {…..}

Delete函数
--从哈希中删除指定的键及其相对应的值
My $person = “justin”;
Delete $books($person);

%ENV哈希
--哈希获取执行环境变量,存取%ENV哈希
$ENV(PATH)



正则表达式 regular expresssion
简易模式
$_ =  “yabba dabba doo”;
If (/abba/) {…..} –表达式/abba/会在$_中寻找这4个字符组成的串,如果找到就返回真
/cake\tsprite/ --会匹配cake、一个制表符和sprite

元字符
--点号(.)配置任何单字符,换行(“\n”)除外
--反斜线(\),在任何元字符前面加上反斜线,就会使他失去元字符的作用;要得到真正的反斜线,用两个反斜线表示;/3\.1415926/得到3.1415926

简易量词
--星号(*)配置前面内容0次或多次的 /fred\t*barney/匹配fred和barney之间有任意多个制表符的串
--(.*)匹配任意字符无限多次,/red.*barney/
--(+)加号,匹配前一个条目一次以上:/fred +barney/
--(?)问号,前一个条目可以出现一次或不出现

模式分组
--()表示分组;/fred+/表示freddddd,/(fred)+/匹配fredfredfred
--反向引用;\1、\2,
$_ = “abba”;
If (/(.)\1/) {…}—圆括号中的点号匹配任何非回车字符,则同’bb’匹配
If(/y(….)d\1/) {..}—匹配y后面连续4个连续的非回车字符,并且用\1在d字符之后重复这4个字符
其中\n代表第n组括号,从左往右
$_ = "yabba";
if (/(.)(.)\2\1/) {
  print "$_ matches\n";--匹配
}
$_ = “AA11BB”;
If(/(.)\111/) {…}; --此时搜寻第111个括号会失败
If( /(.)\g{1}11/ ) {…};--搜寻第一个括号且后面跟上11

择一匹配
--竖线(|),左边或右边匹配都行;/fred|barney|betty/匹配任何含有fred或barney或betty的字符串;
--/fred( |\t)+barney/匹配fred好barney之间空格、制表符或两者组合出现一次以上的字符串,加号表示重复一次或多次
--/fred( +|\t+)barney/,两个单词间一定全是空格或制表符

字符集
--写在方括号[]中,只匹配单个字符,可以是字符集中列出的任何一个
--[a-zA-Z]匹配52个字母中的任何一个
--脱字符^,表示排除在外;[^n\-z]匹配n、-、z以外的任何字符,-前面加反斜线标志转义

字符集简写
--\d代表[0-9];\w表示单写字符[A-Za-z0-9];
--\s相当于[\f\t\n\r ],即换页、制表、换行、回车以及空格,但只是匹配其中一个字符,可以写成\s+匹配一个以上;
--\h匹配横向空白,即[\t ];\v匹配纵向空格,[\f\n\r];\R匹配任何类型的断行

反义简写
--\d、\w、\s的反义简写就是\D,\W.\S,也可写成[^d],[^w],[\s]
--/[\dA-Fa0f]+/匹配16进制数字
--[\d\D]表示任何数字或非数字,即匹配任何字符(而点号匹配换行符以外的任意字符);[^\d\D]


以正则表达式进行匹配
以m//进行匹配
--//为其简写;/^http:\/\//匹配起始的http://,也可以写成m%^http://%

/i进行大小写无关的匹配
Chomp($_ = );
If (/yes/i)—大小写无关的匹配

/s匹配任意字符
--点号无法匹配换行符,而/s可以完成这个任务;它将模式中的每个点号按[\d\D]处理
$_ = “I saw Barney\ndown at the bowling allay\n”;
If (/Barny.*fred/s)—

/x加入空白
--能够在模式里面随意加上空白,更易阅读;
--/-?\d+\.?\d*/可以改写成/ -? \d+ \.? \d* /x,使原始的空白与制表符失去意义;如果还要匹配空白与制表符,就得在前面补上一个反斜线字符;

组合选项修饰符
--在一个模式中使用多个修饰符,可以连在一起使用,先后顺序不会影响匹配的结果
If (/barney.*fred/is) {…}
同样的模式加上注释之后
If (m{
  Barney#小伙子 barney
  .*    #之间的任何东西
  Fred  #大嗓门的fred
  }six)  #同时使用/s,/i和/x

锚位
--默认情况,模式匹配的过程开始于待匹配字符串的开头,若不相符就一直往后推移;锚位可以让模式直接匹配字符串的某处
--脱字符^,表示字符串开头;美元符号$表示字符串结尾;
--/^\s*$/用来匹配空白行,如果不加前后两个锚位,则会把非空白行也一起算进去;

单词锚位
--锚位不局限于字符串的首尾;\b匹配单词边界
--/\bfred\b/只能匹配fred,无法匹配frederick/alfred,此处的单词指一连串的字母、数字与下划线的组合,也就是匹配/\w+/模式的字符;
--非单词边界锚位是\B,能匹配所有\b不能匹配的位置;/\bsearch\B/会匹配searches、searching,但不匹配search、researching;

绑定操作符=~
--默认情况下模式匹配对象为$_,而=~能让perl拿右边的模式匹配左边的字符串,而非$_;
My $some_other = “I dream of betty rubble”;
If($some_other =~ /\brub/) {…}
也可以写成如下方式:
Print “Do you like Perl?”;
My $like_perl = ( =~ /\byes\b/i);--判断回答是否为yes,不区分大小写
If ($like_perl) {…}

模式串中的内插
My $what = shift @ARGV;
While (<>) {
  If (/^($what)/) {--定位于字符串的开头
--如果第一个命令行参数是fred|barney,则模式会变成/^(fred|barney)/,即在每一行开头寻找fred或barney

捕获变量
--一个圆括号代表一个变量,用$1、$2表示
--失败的匹配模式不会改动上次成功匹配时捕获的内容
$_ = “Hello there, neighbor”;
If (/(\S+) (\S+), (\S+)/) {
  Print “$1 $2 $3”;--打印出Hello there neighbor
}
My $dino = “I fear that I’ll be extinct after 1000 years.”;
If($dino =~ /(\d*) years/) {…}
--不捕获模式,允许使用括号但不作捕捉;书写的时候需要在左括号的后面加上?:(问号和冒号);
If (/(?:bronto)?saurus (steak|burger)/) {—不捕获括号跳过bronto
 Print “Fred wants a $1\n”;
}

命名捕捉
My $names = ‘Fred or Barney’;
If ( $names =~ m/(\w+) and (\w+)/ )—不会匹配
If ($names =~ m/(\w+) (and|or) (\w+)/)—可以匹配
  Say “$1, $2”;--输出Fred or,而Barney进入了$3
--而命名捕捉会把结果放进一个特殊的哈希%+,其中的键就是在捕捉时候使用的特殊标签,值就是被捕获的串;
--为捕获串加标签,(?
请登录后发表评论 登录
全部评论

注册时间:2010-03-18

  • 博文量
    375
  • 访问量
    3112454