这里没有软件测试的泛泛理论,只有博主的最佳实践。 博主的研究方向为静态分析和性能测试,致力于各种测试工具的引入、评估和开发。 本博的测试文章均为作者原创,转载请务必注明出处。

小骆驼书作业九:以正则表达处理文本

上一篇 / 下一篇  2008-07-16 14:24:00 / 个人分类:Perl

这章的练习做得不是很顺利,而且我的解答和所谓的标准答案不完全一样,看起来有一点难度了。不过没关系,熟能生巧。

习题一:/(fred|barney){3}/ 可以匹配fredfredfred、fredfredbarney、barneybarneybarney等多种组合,perl还是很聪明的。

习题二:写个程序来复制并修改所指定的文本文件。在副本里,此程序会把出现字符串Fred(大小写不计)的每一处都换成Larry。输入文件名应该在命令行上指定(不询问用户),输出文件名则为本来的文件名加上.out。

#!/usr/bin/perl -w
use strict;

my $in = shift @ARGV;
die "Usage: $0 filename" if not defined $in; #如果没有指定参数则提示错误信息
my $out = $in;
$out =~ s/(\.\w+)?$/.out/;                   #输出文件名改为.out
die "Can not open '$in': $!" unless open IN, "<$in";  #异常处理信息
die "Can not write '$out': $!" unless open OUT, ">$out";
while(<IN>)
{
 s/Fred/Larry/gi;
 print OUT $_;
}

看上去好像很简单,其实这段代码在很严谨的状态下完成了好几件事。不多说,看注释即可。
如果你的程序需要让用户传参数(即在命令行指定),以上的代码是很好的范本。
while(<IN>)比while(<>)要严谨。在用户忘记传参数时,while(<>)会让用户输入多行,Ctrl+D结束,否则会停在那里不动,而while(<IN>)则会提示错误。

习题五:写个程序,把你目前写过的所有程序都加上版权声明,也就是加上一行这样的文字:
##copyright (C) 2008 by YOURS TRULY
把它放在第一行的#!之后。如果文件里已经又版权声明,就不再进行修改。

#!/usr/bin/perl -w
my %do_these;      #建立一个散列,key是文件名称,而其value是什么并不重要
foreach(@ARGV)
{
 $do_these{$_} = 1;
}
#print keys %do_these;
while(<>)        #判断是否已经有版权声明,如果有,则从散列中将这个keys移除
{            #这里就有一个问题。如果用户忘了传文件名即参数,则该程序会一直等待用户输入字符串
 if(/##copyright/i)   #Ctrl + D结束 这样不好
 {
 delete $do_these{$ARGV}
 }
}
#print "\nok1\n";
print keys %do_these;
#print "\nok2\n";
my @ins = sort keys %do_these;
#print "\nok3\n";
$^I = ".bakbak";
foreach $in (@ins)
{
 die "cannot open '$in':$!" unless (open IN, "<$in");
 die "cannot open '$out':$!" unless (open OUT,">$in".$^I);
while(<IN>)        #而这里则避免了上面提到的问题,如果用户忘记输入了,程序会提示一个信息
{                  #然后结束
 if(/^#!/)
 {
  $_ .= "##Copyright (C) 2008\n";
 }
 print OUT $_;
}
}

请看注释,已经非常直观了。想说明的问题尽在其中。

复习笔记

  1. m//模式相当于文字处理器的“查找”,s///则相当于“替换”
  2. /g全局替换
  3. split据说在perl非常有用,当然join也有用
    @chars = split(//, "word");
    print "$_\n" foreach(@chars);
    输出结果为:
    w
    o
    r
    d
    使用split操作符,单词可以分割成字符,句子可以分割成单词,段落可以分割成句子。
    @chars = split(//, $word);
    @words = split(/ /, $sentence);
    @sentences = split(/\./, $paragraph);
  4. /m修饰符之后,所匹配的位置就不再是整个字符串的头尾,而是每行的开发和结尾。

TAG: Perl

 

评分:0

我来说两句

Open Toolbar