perl脚本实践例程

以下为这几天来学习perl脚本语言所写的东东,也算一部分阶段成果咯

过程中还是遇到了许多困难,幸好有网络这个好东东,从前面走过的人那里得到许多帮助

也共享出来,以期对像我一样想学perl的人有些许裨益.......

#!/usr/local/bin/perl

=pod
$num = <STDIN>;//input from keybrd
$val = $num + 0 ;
printf("the number i want to output is %x.\n",$val);
=cut

=pod
$zxy = "zhaoxy";
print(("hello," . $zxy . "!\n") x 3);//连接与重复
=cut


=pod
#字符中的方括号与变量替换
@array = ("aaa".."aad");#列表范围
print("array[1] is:\n $array[1] \n");#aab
print("array[1] is:\n $array\[1] \n");#[1]
print("array[1] is:\n ${array}[1] \n");#[1]
print("array[1] is:\n $\{array}[1] \n");#\n
=cut

=pod
#数组的输出
@array = (1,2,3);
print("@array\n");#1 2 3
print(@array , "\n");#123
=cut

=pod
#当数组变量出现在预期简单变量出现的地方,则PERL解释器取其长度。
$scalar = @array;
printf("the number i want to output is %d.\n",$scalar);
($scalar) = @array;
printf("the number i want to output is %d.\n",$scalar);
=cut

=pod
以数组的长度为循环次数
@array = (1,2,3);
$count =0 ;
while($count < @array)
{
printf("the number i want to output is %d.\n",$array[$count]);
       $count ++;
}
=cut

#数组输出子程序
   sub print_array{
my(@printarray)=@_;
my $count =0 ;
while($count < @printarray)
{
   print("the $count number to output is $printarray[$count]\n");
        $count ++;
   }
}

#数组输出到文件
sub write_array_to_file
{
    my($destfile,@array) = @_;
   print("$destfile written begin.....\n");

    open (DESTFILE, ">>$destfile") || die ("Could not open file $destfile");
   print("file open ok!!\n");
   my $line_cnt = 0 ;
   while($line_cnt < @array){
print DESTFILE ("$array[$line_cnt]\n");
$line_cnt ++ ;
if($line_cnt == @array)
{
        print("file written finished and successfully\n");
   }
    }
    close(DESTFILE);
}

=pod
#子数组应用
@array = (1,2,3,4,5);
@array[1..5] = @array[3,2,4,4,4]; #1,4,3,5,5,5,依此示例可以用子数组形式实现元素交换
$count =0 ;
while($count < @array)
{
print("the number I want to output is $array[$count]\n"); 
    $count ++; 
}
=cut


#以下为三种等效的子程序调用方式
#print_array(@array);
#&print_array(@array);
#do print_array(@array);

=pod
#数组库函数的使用:排序,反转,chop(数组去尾)
@array = ("this","is ",5,"test");
print_array(sort(@array));
print_array(reverse(@array));
print_array(reverse sort(@array));
=cut

=pod
#join/split--连接/拆分
$string = join (
" t ",#连接用的中间字符
       "this","is","a","string");
print($string);
print("\n");
=cut


=pod
$string = "zhaoxy::and::world";
@array = split(/::/    #拆分符号::
             ,$string);
print_array(@array);
cut

=pod
#打开和读取文件
open (CFILE, "perlc.c") || die ("Could not open file");
@array = <CFILE>;
close(CFILE);
print_array(@array);
=cut

=pod
#写入文件
open (DESTFILE, ">perltxt.txt") || die ("Could not open file perltxt");
$line_cnt = 0 ;
while($line_cnt < @array){
print DESTFILE ("$array[$line_cnt]");
$line_cnt ++ ;
if($line_cnt == @array)
{
   print("file written finished and successfully");
}
}

#write_array_to_file("perltxt.txt",@array);#调用子程序实现指定文件写入

=cut

=pod
# ************************************
# ************************************
# <>操作符实际上是对数组@ARGV的隐含的引用 
# PERL也有存储命令行参数的数组@ARGV,可以用来分别处理各个命令行参数;
# 与C不同的是,$ARGV[0]是第一个参数,而不是程序名本身。
# ***************************************
# ***************************************

#从命令行中获取要读的文件名
#打开和读取文件

#方式一
#$para_cnt = 0 ;
#while($para_cnt < @ARGV)
#{
#open (CFILE, $ARGV[$para_cnt]) || die ("Could not open file: $ARGV[$para_cnt]");
= <CFILE>;
#close(CFILE);
#print_array(@array);
#$para_cnt ++ ;
#}


#方式二
#while($line = <>)
#{
#print($line);
#}

#方式三
#while(@array= <>)
#{
#print(@array);
#}
=cut

#管道使用尚未掌握
#用程序的形式也可以象命令行一样打开和使用管道(ex:ls > tempfile
#open(MYPIPE,"|zxymake");
#print("\n zhaoxy would be able to use pipe in program\n");
#close (MYPIPE);

#将字符串用某模式分成多个单词
#$string = "defzhaoxydefcommunicatedefwithdefthedefworlddef!";
= split(/def/,$string);#分隔时第一个元素为空
#print_array(@array);

#匹配操作符=~ !~
#$string = "defzhaoxydefcommunicatedefwithdefthedefworlddef!";
#if($string =~ /commu/) 
#{
#   print("zhaoxy:\thello,perl\n"); 
#} 

=pod
#变量名,数组名,文件名匹配模式          
$string = "$$d_cc";
if($string =~ /^\$[A-Za-z][_0-9a-zA-Z]*$/)#注意$为有特殊意义:串尾匹配
{
print("$string is a legal scalar variable\n");
}elsif($string =~ /^@[A-Za-z][_0-9a-zA-Z]*$/)
{
print("$string is a legal array variable\n");

}elsif($string =~ /^[A-Za-z][_0-9a-zA-Z]*$/)
{
print("$string is a legal file variable\n");
}else
{
print("$string is beyond my reach\n");
}
=cut


#锚模式匹配 ^,$
#$string = "def";
#if($string =~ /^def$/) 
#{
#   print("zhaoxy:\thello,perl\n"); 
#}

#将句子分成单词,模式中的变量替换
#$string = "zhaoxy says hello to the world";
#$pattern = "[ ]+";#[\\t]+用制表符拆分
= split(/$pattern/,$string);
#print_array(@array);

#将句子分成单词
#$string = "zhaoxy says hello to the world";
#$pattern = "]+用制表符拆分
= split(/$pattern/,$string);
#print_array(@array);

#匹配指定数目的字符
#/de{1,3}f/     匹配df中间有1到3个e字符的串

=pod
#$要转义,^不用
#字符"|"指定两个或多个选择来匹配模式
#ex;数字的合法性检查
$mode1 = "^-?\\d+\$";
$mode2 = "^-?0[xX][\\da-fA-F]+\$";#注意式子中的转义符
$num =-0xfa;
if($num =~ /$mode1/ | /$mode2/)#模式选择
{
   print("$num is a legal interger.\n");
}else
{
   print("$num is not a legal interger.\n");
}
=cut

#模式的部分重用
#当模式中匹配相同的部分出现多次时,可用括号括起来,用\n多次引用,以简化表达式
#$mode1 = "}";
#$num ="12-05-92";
#if($num =~ /$mode1/)#模式选择
#{
#   print("$num is legal.\n");
#}else
#{
#   print("$num is not legal.\n");
#}
#****************************
#/\d{2}([\W])\d{2}\1\d{2}/ 不同于/(\d{2})([\W])\1\2\1/ ,后者只匹配形如17-17-17的字符串,而不匹配17-05-91等
#*****************************

#******************************
#注意#的中英文
#&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&


#模式次序变量 
#在模式匹配后调用重用部分的结果可用变量$n,全部的结果用变量$&。
#$mode = "(+) +)";
#$string = "this string contains the number 25.2644";
#$string =~ /$mode/x; #x忽略模式中的空白
#$intergerpart = $1;
#$decimalpart = $2;
#$totalpart    = $&;
#print("$string\nint:$intergerpart\tdecimal:$decimalpart\ttotal:$totalpart\n");

#转义和特定字符的执行顺序
# ()模式内存 # +*?{} 出现次数 # ^$\b\B #锚 |选项#
## 缺省的,模式定界符为反斜线/,但其可用字母m自行指定,如:#
##?? m!/u/jqpublic/perl/prog1! 等价于/\/u\/jqpublic\/perl\/prog1/#
##? 注:当用字母'作为定界符时,不做变量替换;当用特殊字符作为定界符时,#
## 其转义功能或特殊功能即不能使用。#


#模式匹配选项
#g-匹配所有可能模式
#i-忽略大小写
#m-将串视为多行
#o-只赋值一次
#s-将串视为单行
#x-忽略模式中的空白

= "zzzxzy" =~ /z./g;
#print_array(@array);

#匹配的循环
#$string = "zzzxzyzqzwzezd";
#while($string =~ /z./g)
#{
#$match = $&;
#print("$match\n");
#}

#$string = "zzzxzyzqzwzezd";
#while($string =~ /z./g)
#{
#$match = $&;
#$offset = pos($string);#pos函数返回最后一次匹配的位置偏移
#print("$offset\n");
#print("$match\n");
#pos($string) =$offset + 2 ;#设置新的偏移
#}

#/o只作一次变量替换
#下例将出现死循环
#$var = 1;
#$line = <STDIN>;
#while($val < 10)
#{
# $result = $line =~ /$var/o;
# print("$var::::$result\n");
#$line = <STDIN>;
#$var ++;
#}

#模式匹配字符串替换
#$string = "abc123def";
#$string =~ s/123/145/;#abc145def
#print("$string\n");

#替换操作符之选项/e::替换字符串作为表达式

#$string = "0abc1";
#$string =~ s/[a-zA-Z]+/$& x 2 /e;//$&匹配结果
#print($string);

#翻译操作符
#语法:tr/string1/string2/
#$string = "abcdefghijk";
#$string =~ tr/abc/defgh/; #替换超长时忽略多余的defdefghijk
#$string =~ tr/abcde/defg/; #替换长度不足时忽略多余的,用最后一落千丈个字符替换多余的 defggfghijk

#$string = "abcccdcefghijk";
#$string =~ tr/abcccdce/defghijk/; #被替换串某字符多次出现时用替换位置对应的第一个字符替换 cdfffifkghijk
#print($string);

#翻译操作符选项
# c----翻译所有未指定字符
# d----删除所有指定字符
# s----把多个相同的输出字符缩成一个
#ex: tr/\d/ /c 将所有非数字字符替换为空格
#    tr/\t //d 删除tab和空格 
#    tr/0-9/ /cs 把数字间的其它字符替换成一个空格

#$string = "ab*(*&(&cde ( #fgh****ij,..,. k";
#$string =~ tr/a-z/ /cs ;
#print($string);#ab cde fgh ij k


#****************************************************************
#***********************************************************
#扩展模式匹配 语法:(!<c>pattern) c为一字符 pattern为起作用的模式or子模式、
#******************************************************************
#*****************************************************************

#:::::::::::::::::::::::::
#1,不存贮括号内的匹配内容
#:::::::::::::::::::::::::
#$mode = "(+) +)";
#$string = "this string contains the number 25.2644";
#$string =~ /$mode/x; #x忽略模式中的空白
#$intergerpart = $1;
#$decimalpart = $2;
#$totalpart    = $&;
#print("$string\nint:$intergerpart\tdecimal:$decimalpart\ttotal:$totalpart\n");

#注意与上例的区别
#$mode = "(?:\\d+) +)";
#$string = "this string contains the number 25.2644";
#$string =~ /$mode/x; #x忽略模式中的空白
#$intergerpart = $1;
#$decimalpart = $2;
#$totalpart    = $&;
#print("$string\nint:$intergerpart\tdecimal:$decimalpart\ttotal:$totalpart\n");
#int:2644    decimal:         total:25.644

#?option#?option#?option#?option#?option#?option#?option#?option
#2,内嵌模式选项
#?option#?option#?option#?option#?option#?option#?option
#通常模式选项置于其后,有四选项:i、m、s、x可内嵌使用,/(?option)pattern/,等价于/pattern/option。
#$mode = "(?x)(+) 忽略模式中的空白
#$string = "this string contains the number 25.2644";
#$string =~ /$mode/; 
#$intergerpart = $1;
#$decimalpart = $2;
#$totalpart    = $&;
#print("$string\nint:$intergerpart\tdecimal:$decimalpart\ttotal:$totalpart\n");


#?=string#?=string#?=string#?=string#?=string#?=string#?=string#?=string
#3,肯定的与否定的预见匹配
#?=string#?=string#?=string#?=string#?=string#?=string#?=string#?=string
#$mode = "abc(?=[0-9])";
#$string = "25abc833";
#$string =~ /$mode/;
#$matched = $&; #已匹配的模式
#print($matched);

#否定的预见匹配?!
#$string = "25abcdef";
#$string =~ /abc(?![0-9])/;
#$matched = $&; #已匹配的模式
#print($matched);

#until循环
#$counter = 1;
#until(5 == $counter)
#{
#print("zhaoxy says:hello, world\n");
#$counter ++ ;
#}

#for循环
#for($counter = 0;$counter < 5;$counter ++)
#{
#   $line = <STDIN>;
#    print("line$counter:$line\n");
#}

#用foreach控制结构改写输出数组

#数组输出子程序
sub print_array_foreach{
my(@printarray)=@_;
foreach $element (@printarray)
       {
        print("$element "); 
        }
       print("\n");
}

= ("zhaoxy","says","hello","to ","world!");

#print_array_foreach(@array);


#预定义子程序使用
#程序启动时调用
sub BEGIN {
print("welcome to perl test !\n");
}

#程序结束时调用
sub END {
print("perl test end !\n");
}


=pod
###数组实现统计输入文本中的单词及出现次数
       单词列表
        @单词对应次数
#$cntword        @wordlist循环计数
#arraywordlist   记录@wordlist长度

$arraywordlist = 0 ;
$textin = <STDIN>;
chop($textin);#此处不去尾的话,最后一个单词会统计不正确
@array = split(/ \W+/gx,$textin);#分拆文本 非单词字符
@wordlist = @_;
foreach $word (@array)
{     
       $found = 0 ;
for($cntword = 0 ; $cntword < @wordlist; $cntword++)        
       {
           # #########   print($word);
           # ########   print($wordlist[$cntword]);
if( $wordlist[$cntword] eq $word)
               {
            ########    print("found!!!!");
                $found =1 ; 
                last;     #待找单词已统计过则跳过
                }

       }
   ############ print("the counter is $cntword\n");
       if($found){
   $wordcnt[$cntword] ++; #增加单词计数
}else{
             $arraywordlist = @wordlist;#统计过的单词列表
             $wordlist[$arraywordlist] = $word;#新单词增加到列表中
             $wordcnt[$arraywordlist] = 1 ;#新单词计数为1
             
       }
}
print_array(@wordlist);
print_array(@wordcnt);
=cut

###采用关联数组(哈稀表)实现统计输入文本中的单词及出现次数
###关联数组总是随机存贮的,因此有keys()访问所有元素时并不保证以任何顺序出现
###特别是它们不会以被创建的顺序出现
=pod
$textin = <STDIN>;
chop($textin);#此处不去尾的话,最后一个单词会统计不正确
@array = split(/ \W+/gx,$textin);#分拆文本 非单词字符
foreach $word (@array)
{
$wordlist{$word} += 1 ; #哈稀表使用方法     
}
sort %wordlist;
   foreach $capword (sort keys(%wordlist)) #排序
    {
   print("$capword:    $wordlist{$capword}\n");   
   }
=cut


#将关联数组赋给数组
= %wordlist;#??注意,此语句中元素次序未定义
#print_array(@array);

#将数组赋给关联数组
= ("hello",3,"zhao",2,"yun",1);#须为偶数项
#%wordlist = @array;
# foreach $capword (sort keys(%wordlist)) #排序
# {
# print("$capword:    $wordlist{$capword}\n");   
# }

#用列表给关联数组赋值
#%fruit = ("apples",17,"bananas",9,"oranges","none");
#%fruit = ("apples"=>17,"bananas"=>9,"oranges"=>"none");

#删除关联数组元素
#唯一方法:用内嵌函数delete
#注意一定不要对关联数组用内嵌函数push,pop,shift,splice,因元素位置是随机的
= ("hello",3,"zhao",2,"yun",1);#须为偶数项
#%wordlist = @array;
#delete($wordlist{"zhao"});#删除元素
# foreach $capword (sort keys(%wordlist)) #排序
# {
# print("$capword:    $wordlist{$capword}\n");   
# }

#关联数组下标列表 keys(%wordlist)
#关联数组值的列表 values(%wordlist)

#用关联数组循环更有效的方式,用函数each
# while(($holder,$record) == each(%records)){}
#千万不要在each循环中添加和删除元素,否则会产生不可预料的后果


#################################
################################
#用关联数组实现各种数据结构
#################################
#################################

#1,单链表
#待处理数据个数未知或随程序运行而增长
#本例实现功能:用链表按字母次序输出一个文件中的单词

=pod
sub add_word_to_list
{
    my ($word) = @_;;

    if($head eq "") #empty list
    {
        $head = $word;
        $wordlist{$word} ="";
     }    
      if($head eq $word){#word与head相同 
     }elsif($head gt $word)    #word放在head前
     {
   $wordlist{$word} = $head;
       $head = $word;
     }else{

    #非以上情况,查找适当位置
    $pointer = $head;
    while($wordlist{$pointer} ne "" && ($wordlist{$pointer} lt $word ))
    {
         $pointer = $wordlist{$pointer};
      }

       if($word eq $wordlist{$pointer})#相同则不插入

}else{
     $wordlist{$word} = $wordlist{$pointer};
     $wordlist{$pointer} = $word;
     } 
   }
}


sub print_list
{
    print("words in the text:\n");
    $pointer = $head;
    while($pointer ne "")
     {
      print("$pointer\n");
      $pointer = $wordlist{$pointer};
      }
}

#子程序定义注意事项,如只需要传递简单变量参数,则函数名后面的括号不需要
sub printstring
{
my($str) = @_;
print("$str\n");
}

$textin = <STDIN>;
chop($textin);#此处不去尾的话,最后一个单词会统计不正确
@array = split(/ \W+/gx,$textin);#分拆文本 非单词字符
foreach $element(@array)
{
$element =~ tr/A-Z/a-z/; #将字符全转为小写
    add_word_to_list($element);

##printstring($element);
   
}
print_list();
=cut

=pod
#关联数组模拟结构体
#struct {
#int field1;
#int field2;
#int field3;
#}mystruct;

%mystruct = ("field1","","field2","","field3","");
$mystruct{"field1"} = "perl";
$mystruct{"field2"} = "with";
$mystruct{"field3"} = "kaka";
@array = %mystruct;
print_array(@array);
=cut


=pod
#树的实现
#有多种使用关联数组实现树结构的方法,最好的一种应该是:
#给子节点分别加上left和right以访问之

$rootname = "parent";
%tree = ("parentleft","child1",
          "parentright","child2",
          "child1left","grandchild1",
           "child1right","grandchild2",
            "child2left","grandchild3",
            "child2right","grandchild4");
#遍历并打印
&print_tree($rootname); #line646

sub print_tree{
local ($nodename) = @_;
local($leftchildname,$rightchildname);

$leftchildname = $nodename . "left";
$rightchildname = $nodename . "right";

print("$nodename\n");#中序
if($tree{$leftchildname} ne ""){
&print_tree($tree{$leftchildname});
}

#print("$nodename\n");#左序
if($tree{$rightchildname} ne ""){
&print_tree($tree{$rightchildname});
}
#print("$nodename\n");#右序

}
=cut
####################考虑实现一棵动态的


###############################
#########################
#格式化输出
#########################
################################
=pod
$~ = "MYFORMAT";#指定格式,如不指定则解释器试图使用名为STDOUT的打印格式
write;

format MYFORMAT = 
=====================================
Here is the text I want to display.
=====================================
.
=cut


#输出文本中出现次数前五的字母
=pod    
$textin = <STDIN>;
chop($textin);#此处不去尾的话,最后一个单词会统计不正确
@array = split(/ \W+/gx,$textin);#分拆文本 非单词字符

foreach $word (@array)
{
@letters = split(//,$word);#分拆单词
foreach $letter (@letters)

$lettercount{$letter} ++;
    }
}

sub occurrences{
$lettercount{$a} <=> $lettercount{$b};######???????
}

foreach $letter (reverse sort occurrences(keys(%lettercount)))

&write_letter($letter,$lettercount{$letter});
     last if(++$count == 5);
    }

sub write_letter{
local($letter,$value) = @_; #注意此处用local而不能用my
$~ = "WRITELETTER";
write;
}
format WRITELETTER = 
     @:@
     $letter,$value
.

=cut


=pod
###########################
#格式化输出到其它文件
######################3
#$~变量只对缺省文件变量起作用

sub write_to_stdout{
local ($savefile,$saveformat);
$saveformat = $~;               #保存先前输出格式 
$savefile = select(STDOUT);      #改变缺省文件
$~ = MYFORMAT;
write;
$~ = $saveformat;                #恢复
select($savefile);               #恢复
}

format MYFORMAT = 
=====================================
Here is the text I want to display.
=====================================
.

write_to_stdout();
=cut

#//line792

###分页:
###打印页眉:定义名为filename_TOP的打印格式如给标准输出文件定义页眉如下:format STDOUT_TOP=
####当前页码系统变量$%
####页长(缺省为60行)系统变量:$= 须出现在第一个write语句前
#### 一般使用分页机制时不用print函数,因为用write输出是perl解释器会跟踪每页的当前行号
####如必须使用print而又不打乱页计数,可调整系统变量$-(当前行到页末的行数)
#调整方法如下:
#print("here is a line of output\n";
#$- -=1;


#####格式化长字符串
##值域@*可输出多行文本:原样输出
##对长串格式化值域为把打头的@字符换成^就可以了(一行中放置尽可能多的单词)


@quotation = <STDIN>;
$quotation = join("",@quotation);
$~ = "MYFORMAT";
write;

format MYFORMAT = 
=====================================
Here is the text I want to display.
~ ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
$quotation 
~ ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
$quotation 
=====================================

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值