LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
查看: 43437|回复: 86

有关Perl问题的讨论请到这里

[复制链接]
发表于 2003-9-15 21:51:59 | 显示全部楼层 |阅读模式
由于论坛里有关perl的帖子逐渐增多,学习讨论Perl的热情很高,所以我决定建立一个专门讨论perl的栏目,凡是和perl相关的,都发到这里来!

perl 的全称是  Practical Extraction and Report Language

Perl资源:
http://www.perl.org/
http://www.perl.com/
http://www.cpan.org/         综合perl文档网络
http://search.cpan.org/       
http://www.cpan.org/scripts/index.html   很多的脚本范例
http://kobesearch.cpan.org/
http://comp.lang.perl.moderated/   新闻组
http://www.perlmonks.org/   这里有很多书籍
http://www.oreilly.com.cn   oreilly的中文站点
http://www-900.ibm.com/developerWorks/cn/linux/sdk/perl/
http://www.huixinyi.com/hxschool/perllesson/  一个学习perl的中文站点

以下的学习站点由论坛的兄弟提供!!有的提供几个,我就不写上名字了。请大家见谅!!!
http://learn.perl.org/library/beginning_perl/
以上的书是完整的。
http://www.cpan.org
学习perl的园地。
http://linux.ccpi.gov.cn/Linux/PERL/PERL.HTM
不错的选择
国内的
www.perlchina.org
www.ilcatperl.org
是公司三明治和飞云hoowa的站点,很有名,也很有影响力
Perl 5 中文教程
http://dngy.html.533.net/cgi/perl/perl.html
http://www.yuzi.net/perl5/ 中文CGI专门店
o'reilly网站的perl文档:
http://www.perl.com/pub/q/documentation
Perl的站点实在很多啦~~,到网上搜一下就很多的说 ;)

在这里引用别人的文章简单介绍一下perl
Perl是什么?

  Perl是一种解释型的高级语言,由 Larry Wall和其他许多人所写,融合了许多语言的特性。它主要是由无所不在的 C语言,其次由 sed、awk,UNIX shell 和至少十数种其他的工具和语言所演化而来。据Larry说,他将其他语言中的精华凝聚在Perl中,而抛弃了那些看起来不够好的。
  Perl对进程、文件和文字有很强的处理能力,操作灵巧方便,已经成为web上主要的脚本语言,绝大部分的CGI是用Perl写的。不但如此,Perl作为一种快捷的语言原形,在让不同的系统一起工作方面也有广泛的应用。许多系统管理员都在用Perl完成各种各样繁多的系统管理。有关快速原型设计、系统工具、软体工具、系统管理、资料库连结、图像程式设计、网路连结,和 WWW程式设计等之类的任务,都特别 适合用 Perl来做。
  Perl是在UNIX上发展起来的,但是现在有适合各种系统的版本。而且Perl是解释型的语言,它在不同的平台间具有很好的移植性。
  其实,Perl不只是一种编程语言,它是Internet文化的一部分,它提供了一种全新的思维方法。

Perl对环境的要求

    * Most UNIX variants
    * DOS
    * Windows
    * OS/2
    * VMS
    * QNX
    * BeOS
    * Amiga

  呵呵,还有哪里是空白?

谁对 perl提供支援?由谁负责发展?它为什麽是免费的?

  Perl自由开放的发行方式要归功於发烧前的 Internet的传统文化及其作者 Larry Wall。Perl是由使用者提供支援。现在 Perl的核心、标准程式库、选择性安装的模组,以及您现在正在阅读的使用说明都出自於义务者之手。详情请见 perl原始码发行版中所附的 README档案底部的私人注记。
值得一提的是,核心发展小组(称为 Perl Porters)的成员是一群高度热情奉献的人仕,全心投入发展出比您所能想像、用钱能买得到还要更好的免费软体。您可经由 news://genetics.upenn.edu/perl.porters-gw/http://www.frii.com/~gnat/perl/p ... 新近发展计画 的情报。

  尽管 GNU计画将 Perl囊括在它的发行中,但是没有叫「GNU Perl」这样的东西。 Perl既非自由软体基金会所创,亦非由其负责维护。Perl的发行条款同时也较 GNU软体更来得开放。

  如果您愿意,您可以购买商业性的 Perl支援。但对大多数使用者来说,非正式性的支援通常已相当足够。详情请见「到哪里可买到商业性的 Perl支援」一问的回 答。

Perl难学吗?

  Perl不但容易上手,也容易继续学下去。它看起来和大多数您可能已接触过的语言一样。所以如果您只写过 C 程式、或 awk script、shell script,或甚至只是 Excel的 macro(巨集),您已经在半路了。
大多数的任务只需要 Perl语言的一小部分即可完成。发展 Perl程式的座右铭即是「不只一种方法可以达到」(TMTOWTDI; There's More Than One Way To Do It, 有时读作「堤姆投迪」)。因此,Perl的学习曲线是既平(易学)且长的(如果您要的话,有一大堆够您学的)。

  最後,Perl(通常)算是解译式的语言。也就是说您写了程式後不需经由一道中间的编码过程即可测试;这让您可以很快、很容易地测试及除错。这个方便试验的特性又让学习曲线变得更加平坦。

  有助於修习 Perl 的一些事:UNIX经验、对几乎是任何一种程式语言的经验、了解 regular expressions(正规表示法),以及看得懂旁人写的程式的能力。如果您有什麽想用 Perl来做的事,那麽可能已经有前人做过了,而且实例通常可免费取得。还有别忘了新的 Perl模组。模组在这份 FAQ 的第叁部分有详细的讨论,还有【别忘了您的好朋友】 CPAN,这会在第二部分谈到。

Perl和其他的程式语言比起来如何?例如 Java, Python, REXX, Scheme,或 Tcl?

  Perl在某些地方比较好,某些地方较差。精确地说到底哪些方面好或坏通常视个人偏好而定,所以在新闻讨论组中问这种问题很可能会掀起一场毫无建设性的圣战。

  要比较各语言的异同最好的方法是试着用不同的语言写功能相同的程式。各程式语言都各有属於它们各自的新闻讨论组,您可从中学习(但希望您不是去和人辨论吵架的)。

我可以用 Perl来做【某种差事】吗?

  Perl有足够的弹性和扩充性,从只需要写短短一行的档案处理工作到复杂的系统,几乎没有什麽做不到的。对有些人来说,Perl的是拿来做写 shell程式的理想替代品。其他人则用高阶的 Perl来替代处理许多原先需要用 C或 C++ 一类的低阶语言来达到的程式。哪些差事决定要用 Perl来处理,这一切都得看您(或许还有您的经理...)。

  如果您有一个提供 API的程式库的话,您可用 C或 C++来写一个 Perl 延伸,然後便可透过它将程式库中的任何一部分动态载入您的 Perl主程式中。您也可以 反过来,用 C或 C++来写主程式,然後以即时动态载入的方式插入一些Perl程式码,产生一个威力强大的应用程式。

  话虽如此,对解决某些特定的问题,使用小型、专精,专为特殊用途设计的语言总 是比较方便的。 Perl的设计是尽力地满足各种不同人的需要,因而不特别偏颇任何人。至於特殊功能语言的例子,随便举两个,譬如 prolog 和 matlab 便是。

哪些场合下不适合用 Perl?

  当您的主管禁止的时候 -- 不过请务必考虑把他们换掉 :-)。
说真的,如果您已经有用另一个语言写成的应用程式(而且写得很好)的时候,或者是已经有替某些特定的工作设计的语言(例如:prolog, make),这个时候就不需要用 Perl。

  由於种种因素,Perl大概不太适合拿来做即时内嵌式系统、属於低层级的作业系统发展工作,例如周边设备的 drivers或环境转换码、复杂的多线共用记忆体应用程式,或非常大的应用程式。您会发现 Perl 本身便不是以 Perl写成的。

  刚出炉的 Perl纯码编译器或许可帮忙去除一些上述的限制,但您要了解:Perl在本质上仍是一活性变数语言 (dynamically typed language),而非固性变数 (statically typed)。只要您不将核电厂或脑科手术监视器所用的程式放心地用 Perl来写,您自然就不会闯祸遭殃。这样 Larry晚上也可以睡得安稳些 --股市分析程式不在此限 :-)。

Perl程式应算是 program还是 script?

  都无所谓。
按标准术语来讲,program指已经由编译程序编译好、转为机器码,可多次执 行的程式;而 script则是每次执行时都必须透过一个解译程式来解译。然而,Perl程式严格说来,既非编译 (compiled) ,亦非解译式 (interpreted);因 Perl程式可转译成位元码形式存在(可说是某种 Perl虚拟机器 [virtual machine]),或转译为完全不同的语言,如 C或组合语言。所以光看原始码很难 说它到底是替纯解译器、或是 parse-tree解译器、位元码解译器,还是纯码编译器而写;因此这题很难给它一个确切的答案。

COMEFROM  THIS LINK:
http://www.skybamboo.com/perl/intro/what_is_perl.htm

祝:大家学习愉快 !
发表于 2003-9-15 21:56:43 | 显示全部楼层
呵呵,多谢版主,近来正在学习perl,呵呵,多谢多谢,

版主什么时候把perl加入这个版啊,赶快啊,
 楼主| 发表于 2003-9-15 22:03:01 | 显示全部楼层
最初由 xiaoniao9312 发表
呵呵,多谢版主,近来正在学习perl,呵呵,多谢多谢,

版主什么时候把perl加入这个版啊,赶快啊,

新建立版块那得向上级申请,等我们这里成熟了,我想一定会有真正的讨论区的!
我也刚刚开始学习perl,(正看入门的书呢 ),希望我们互相帮助,共同提高!!!
 楼主| 发表于 2003-9-15 22:10:47 | 显示全部楼层

Perl 中的正则表达式[转贴]

来自:http://263.aka.org.cn/Lectures/002/Lecture-2.1.2/perl-reg.html
特此感谢!
********************************************************************
正则表达式的三种形式
正则表达式中的常用模式
正则表达式的 8 大原则

      正则表达式是 Perl 语言的一大特色,也是 Perl 程序中的一点难点,不过如果大家能够很好的掌握他,就可以轻易地用正则表达式来完成字符串处理的任务,当然在 CGI 程序设计中就更能得心应手了。下面我们列出一些正则表达式书写时的一些基本语法规则。

9.1 正则表达式的三种形式

首先我们应该知道 Perl 程序中,正则表达式有三种存在形式,他们分别是:


匹配:m/<regexp>/ (还可以简写为 /<regexp>/ ,略去 m)


替换:s/<pattern>/<replacement>/


转化:tr/<pattern>/<replacemnt>/


这三种形式一般都和 =~ 或 !~ 搭配使用(其中 "=~" 表示相匹配,在整条语句中读作 does,"!~" 表示不匹配,在整条语句中读作 doesn't),并在左侧有待处理的标量变量。如果没有该变量和 =~ !~ 操作符,则默认为处理 $_ 变量中的内容。举例如下:


$str = "I love Perl";
$str =~ m/Perl/; # 表示如果在 $str 中发现 "erl" 字符串,则返回 "1" 否则返回 "0"。
$str =~ s/Perl/BASH/; # 表示将变量 $str 中的 "erl" 字符串替换为 "BASH",如果发生此替换则返回 "1",否则返回 "0"。
$str !~ tr/A-Z/a-z/; # 表示将变量 $str 中的所有大写字母转化为小写字母,如果转化发生了则返回 "0",否则返回 "1"。


另外还有:


foreach (@array) { s/a/b/; } # 此处每次循环将从 @array 数组中取出一个元素存放在 $_ 变量中,并对 $_ 进行替换处理。
while (<FILE>) { print if (m/error/); } # 这一句稍微复杂一些,他将打印 FILE 文件中所有包含 error 字符串的行。


Perl 的正则表达式中如果出现 () ,则发生匹配或替换后 () 内的模式被 Perl 解释器自动依次赋给系统 $1, $2 ...... 请看下面的例子:


$string = "I love perl";
$string =~ s/(love)/<$1>/; # 此时 $1 = "love",并且该替换的结果是将 $string 变为 "I <love> perl"
$string = "i love perl";
$string =~ s/(i)(.*)(perl)/<$3>$2<$1>/; # 这里 $1 = "i",$2 = " love ",$3 = "perl",并且替换后 $string 变为 "<perl> love <i>"


替换操作 s/<pattern>/<replacement>/ 还可以在末尾加上 e 或 g 参数,他们的含义分别为:


s/<pattern>/<replacement>/g 表示把待处理字符串中所有符合 <pattern> 的模式全部替换为 <replacement> 字符串,而不是只替换第一个出现的模式。
s/<pattern>/<replacement>/e 表示将把 <replacemnet> 部分当作一个运算符,这个参数用的不多。


比如下面的例子:


$string = "i:love:perl";
$string =~ s/:/*/; #此时 $string="i*love:perl";
$string = "i:love:perl";
$string =~ s/:/*/g; #此时 $string="i*love*perl";
$string =~ tr/*/ /; #此时 $string="i love perl";
$string = "www22cgi44";
$string =~ s/(\d+)/$1*2/e; # (/d+)代表 $string 中的一个或多个数字字符,将这些数字字符执行 *2 的操作,因此最后 $string 变成了 "www44cgi88"。


下面给出一个完整的例子:


#!/usr/bin/perl

print"请输入一个字符串!\n";
$string = <STDIN>; # <STIDN>代表标准输入,会让使用者输入一字符串
chop($string); # 将$string最后一个换行的字符\n删除掉
if($string =~ /perl/){
  print("输入的字符串中有 perl 这个字符串!\n";
}


如果输入的字符串含有 perl 这个字符串的话,就会显示后面的提示信息。





9.2 正则表达式中的常用模式


下面是正则表达式中的一些常用模式。


/pattern/
结果


.
匹配除换行符以外的所有字符


x?
匹配 0 次或一次 x 字符串


x*
匹配 0 次或多次 x 字符串,但匹配可能的最少次数


x+
匹配 1 次或多次 x 字符串,但匹配可能的最少次数


.*
匹配 0 次或一次的任何字符


.+
匹配 1 次或多次的任何字符


{m}
匹配刚好是 m 个 的指定字符串


{m,n}
匹配在 m个 以上 n个 以下 的指定字符串


{m,}
匹配 m个 以上 的指定字符串


[]
匹配符合 [] 内的字符


[^]
匹配不符合 [] 内的字符


[0-9]
匹配所有数字字符


[a-z]
匹配所有小写字母字符


[^0-9]
匹配所有非数字字符


[^a-z]
匹配所有非小写字母字符


^
匹配字符开头的字符


$
匹配字符结尾的字符


\d
匹配一个数字的字符,和 [0-9] 语法一样


\d+
匹配多个数字字符串,和 [0-9]+ 语法一样


\D
非数字,其他同 \d


\D+
非数字,其他同 \d+


\w
英文字母或数字的字符串,和 [a-zA-Z0-9] 语法一样


\w+
和 [a-zA-Z0-9]+ 语法一样


\W
非英文字母或数字的字符串,和 [^a-zA-Z0-9] 语法一样


\W+
和 [^a-zA-Z0-9]+ 语法一样


\s
空格,和 [\n\t\r\f] 语法一样


\s+
和 [\n\t\r\f]+ 一样


\S
非空格,和 [^\n\t\r\f] 语法一样


\S+
和 [^\n\t\r\f]+ 语法一样


\b
匹配以英文字母,数字为边界的字符串


\B
匹配不以英文字母,数值为边界的字符串


a|b|c
匹配符合a字符 或是b字符 或是c字符 的字符串


abc
匹配含有 abc 的字符串


(pattern)
() 这个符号会记住所找寻到的字符串,是一个很实用的语法。第一个 () 内所找到的字符串变成 $1 这个变量或是 \1 变量,第二个 () 内所找到的字符串变成 $2 这个变量或是 \2 变量,以此类推下去。


/pattern/i
i 这个参数表示忽略英文大小写,也就是在匹配字符串的时候,不考虑英文的大小写问题。


\
如果要在 pattern 模式中找寻一个特殊字符,如 "*",则要在这个字符前加上 \ 符号,这样才会让特殊字符失效




下面给出一些例子:   


范例
说明


/perl/
找到含有 perl 的字符串


/^perl/
找到开头是 perl 的字符串


/perl$/
找到结尾是 perl 的字符串


/c|g|i/
找到含有 c 或 g 或 i 的字符串


/cg{2,4}i/
找到 c 后面跟着 2个到 4个 g ,再跟着 i 的字符串


/cg{2,}i/
找到 c 后面跟着 2个以上 g ,再跟着 i 的字符串


/cg{2}i/
找到 c 后面跟着 2个 g,再跟着 i 的字符串


/cg*i/
找到 c 后面跟着 0个或多个 g ,再跟着 i 的字符串,如同/cg{0,1}i/


/cg+i/
找到 c 后面跟着一个以上 g,再跟着 i 的字符串,如同/cg{1,}i/


/cg?i/
找到 c 后面跟着 0个或是 1个 g ,再跟着 i 的字符串,如同/cg{0,1}i/


/c.i/
找到 c 后面跟着一个任意字符,再跟着 i 的字符串


/c..i/
找到 c 后面跟着二个任意字符,再跟着 i 的字符串


/[cgi]/
找到符合有这三个字符任意一个的字符串


/[^cgi]/
找到没有这三个字符中任意一个的字符串


/\d/
找寻符合数字的字符,可以使用/\d+/来表示一个或是多个数字组成的字符串


/\D/
找寻符合不是数字的字符,可以使用/\D+/来表示一个或是更多个非数字组成的字符串


/\*/
找寻符合 * 这个字符,因为 * 在常规表达式中有它的特殊意思,所以要在这个特殊符号前加上 \ 符号,这样才会让这个特殊字符失效


/abc/i
找寻符合 abc 的字符串而且不考虑这些字符串的大小写





9.3 正则表达式的八大原则


  如果在 Unix 中曾经使用过 sed、awk、grep 这些命令的话,相信对于 Perl 语言中的正则表达式(Regular Expression)不会感到陌生。Perl 语言由于有这个功能,所以对字符串的处理能力非常强。在Perl语言的程序中,经常可以看到正则表达式的运用,在 CGI 程序设计中也不例外。


  正则表达式是初学 Perl 的难点所在,不过只要一旦掌握其语法,你就可以拥有几乎无限的模式匹配能力,而且 Perl 编程的大部分工作都是掌握常规表达式。下面给大家介绍几条正则表达式使用过程中的 8 大原则。


  正则表达式在对付数据的战斗中可形成庞大的联盟--这常常是一场战争。我们要记住下面八条原则:


* 原则1:正则表达式有三种不同形式(匹配(m/ /),替换(s/ / /eg)和转换(tr/ / /))。


* 原则2:正则表达式仅对标量进行匹配( $scalar =~ m/a/; 可以工作; @array =~ m/a/ 将把@array作为标量对待,因此可能不会成功)。


* 原则3:正则表达式匹配一个给定模式的最早的可能匹配。缺省时,仅匹配或替换正则表达式一次( $a = 'string string2'; $a =~ s/string/ /; 导致 $a = 'string 2')。


* 原则4:正则表达式能够处理双引号所能处理的任意和全部字符( $a =~ m/$varb/ 在匹配前把varb扩展为变量;如果 $varb = 'a' $a = 'as',$a =~ s/$varb/ /; 等价于 $a =~ s/a/ /; ,执行结果使 $a = " s" )。


* 原则5:正则表达式在求值过程中产生两种情况:结果状态和反向引用: $a=~ m/pattern/ 表示 $a 中是否有子串 pattern 出现,$a =~ s/(word1)(word2)/$2$1/ 则"调换"这两个单词。


* 原则6:正则表达式的核心能力在于通配符和多重匹配运算符以及它们如何操作。$a =~ m/\w+/ 匹配一个或多个单词字符;$a =~ m/\d/" 匹配零个或多个数字。


* 原则7:如果欲匹配不止一个字符集合,Perl使用 "|" 来增加灵活性。如果输入 m/(cat|dog)/ 则相当于"匹配字符串 cat 或者 dog。


* 原则8:Perl用 (?..) 语法给正则表达式提供扩展功能。(这一点请同学们课后看相关资料)


想要学习所有这些原则?我建议大家先从简单的开始,并且不断的尝试和实验。实际上如果学会了 $a =~ m/ERROR/ 是在 $a 中查找子串ERROR,那么你就已经比在 C 这样的低层语言中得到了更大的处理能力
 楼主| 发表于 2003-9-15 22:14:10 | 显示全部楼层

Perl 的简单语法(与 C 语言的异同)

基本输入输出


分支循环控制结构


函数


常用系统调用


文件操作


进程管理


7.1    基本输入输出


在 BASH 脚本程序中,我们用 read var 来实现从键盘的输入,用 echo $var 来实现输出。那么在 Perl 中将有一点变化。Perl 中将标准输入用关键词 <STDIN> 表示;标准输出用 <STDOUT> 表示,标准错误输出用 <STDERR> 表示。故而从标准输入读取数据可以写成:


$var=<STDIN>; # 读取一行输入,并存入变量 $var 中。
@var=<STDIN>; # 读取多行输入,并存入数组 @var 中。


在 Perl 语言中,变量 $_ 是许多操作符的缺省变量。因此如果需要读入许多行并对每行分别处理一般这样写:


   while($_=){
    chop($_); # chop 调用用于去掉 $_ 变量中的最后一个字符(换行符)。
    # 处理$_(每一行)
   }


或者可以简写为:


   while(){
    chop; # 等同于chop($_)
    # 处理$_(每一行)
   }


如果 <> 括号之间没有任何字符,则表示从命令行所指示的文件中读取数据,看下面这个例子(read.pl):


   #!/usr/bin/perl;

   while(<>){
    print $_;
   }


如果在命令行输入 $ perl read.pl read.pl 。这个程序将在屏幕上打印出文件 read.pl 的每一行。


在前面的例子中我们已经看见,Perl 语言中向标准输出输出数据可以用 print 语句。我们在 print 语句中可以输出多个变量,变量之间用 "," 分隔开来。如下面的例子:


   print 3,45*2,"hello",2+2;


上面的输出语句将给出 "390hello4" 的输出结果。


除了 print 语句以外,Perl 中还提供了一个 printf 语句用于标准输出,不过 printf 更接近于 C 语言的 printf 函数,可以进行格式化的输出,如:


   printf "%10s% 8d%8.2f\n",$a,$b,$c;
   printf("%10s% 8d%8.2f\n",$a,$b,$c); # 加上括号的 C 语言写法也是可以的。



另外 print 和 printf 在输出数组变量的时候也是不同的,如下例:


@a = (1 , 2, 3);
printf @a;
print "\n";
print @a;
print "\n";


输出的结果是:


1
123


如果在 @a 两边加上 "" ,则输出就都是 123了。





7.2    分支循环控制结构


if 语法


Perl 语言的 if...then...else... 语句结构和 C 语言非常相似,该结构一共有三种变种,分别如下:


if 语法 1:


if(判别运算式)
{
  表达式为真时的语句块;
}


或写成:表达式为真时的语句 if (判别运算式);


实例为:print "您的分数及格了!\n" if ($score>=60);


if 语法 2:


if(判别运算式一){
  判别式一为真时的语句块;
}else{
  判别式一为假时的语句块;
}


if 语法 3:


if (判别运算式一)
{
  判别式一为真时的语句块;
}elsif(判别运算式二){
  判别式二为真时的语句块;
}elsif(判别运算式三){
  判别式三为真时的语句块;
}else{
  所有判别式为假时的语句块;
}


unless 语法


unless的含义就是说"如果判别式不为真,就执行..."。


unless 语法 1:


unless(判别运算式) {
  判别式为假时语句块;
}


或写为:判别式为假时语句 unless (判别运算式);



unless 语法 2:


unless(判别运算式)
{
  判别式为假时语句块;
}else{
  判别式为真时语句块;
}


进阶技巧:"&&"、"||" 及 "? :"


这些符号看上去像标点符号,或是表达式的一部分。和 C 语言中一样,他们在 Perl 语言中也可作为控制结构,而且更简洁,只是可读性差了很多。


比如说:

 if (判别表达式) {为真时语句块};


也可以写为:

 判别表达式 && 为真时的语句块


同样道理,unless(this){that} 可替换为 this||that。

? : 则可以这样使用:


exp1?exp2:exp3


这个式子表示:如果 exp1 为真则求 exp2 的值,否则求 exp3 的值。


while 循环语法


Perl 语言中 while, do...while, for, until, foreach 均可以用于实现循环结构,循环中还可以用 last,next,redo 等操作符进行控制。下面我们先介绍 while 语法。


while(判别运算式) {
  程序叙述区块;
}


上个语法在Perl中也可以写成: 程序叙述区块 while(判别运算式);


do...while 循环语法


do
{
  程序叙述区块;
}while(判别运算式);



在 while 和 do while 循环最大的区别是在 do while 循环中,循环体至少会被执行一次。


until 循环语法


until(判别运算式)
{
   程序叙述区块;
}


上个语法在Perl中也可以写成: 程序叙述区块 until (判别运算式);


do...until 循环语法


do{
   程序叙述区块;
}until (判别运算式);


for 循环语法


for (初始化运算式;判别运算式;循环过程运算式)
{
  程序叙述区块;
}


或者


for $variable(@array)
{
  程序叙述区块;
}



第二个语法中如果把 $variable 变量省略的话,就会将数组 @array 的元素一个一个指定给 $_ 这个变量,这是比较精简的写法。其中第一个语法更接近于 C 语言的语法。


foreach 循环语法


foreach $variable(@array)
{
  程序叙述区块;
}


如果把$variable变量省略的话,就会将数组@array的元素一一指定给$_这个内定的输出变量.


last 退出循环语法


范例:


for($i=1;$i<=10;$i++)
{
  last if ($i==5); # 如果 $i 等于5的话就退出 for 循环
  print"$i\n";
}


next 继续循环语法


范例:


for($i<=10;$i++)
{
  # 如果是 2 的倍数的话,就到循环的下一个陈述
  next if($i%2)==0)
    print"$i是一个奇数!\n";
}








7.3    函数


Perl 语言中有两种函数,一种是 Perl 自带的一些实用系统函数,如文件打开函数 open 等;另一种是用户自定义的函数,用户通过自己定义函数可以使得程序的结构化更加清晰。


用户函数又称子程序(Subroutine),在 Perl 中用下面的结构来定义用户函数:

  sub 子程序名{
     语句块;
  }

这里的子程序名与变量的取名规则类似。

与 BASH 程序不同,Perl 中的用户函数的定义可以位于程序的任何位置,比如说放在文件的未尾,而并不需要放在调用该函数的代码之前。如果两个子程序使用了相同的程序名,位置靠后的子程序将覆盖前面子程序。

需要注意的是用户函数中的变量默认为全局变量,并不是像 C 语言中那样是局部变量,Perl 函数中的变量可以被其他程序段共享。如果希望定义局部变量,可以用下面两种方法来实现:


local($a);
my $a;

另外用户函数的调用:通过在子程序前加"&"符号才可以,函数可在任一表达式内被调用。函数调用可以嵌套,即子程序中可以再调用另外的子程序,即可以程序员可以用 Perl 写出具有递归特性的代码。

调用用户函数产生的结果称为返回值(return value)。返回值是每次函数被执行时,最后一个被执行到的表达式的计算结果。如:


sub add_a_b{
      $a+$b;
}

函数最后一条表达式为 $a+$b,故返回值为 $a+$b 的计算结果。以下是调用情况:

$a = 5;
$b = 6;
$c = &add_a_b; # $c 的值为 11
$d = 5 * &add_a_b; # $d 的值为 5*11,即 55

还有一个问题是,在 Perl 程序中如何向函数中传递参数呢?这是可以实现的,调用函数时,可以将参数依次放在函数名后面的 "()" 中,而在函数体中,系统默认数组 @_ 中就按同样顺序存放着所有的参数。我们可以访问 @_ 变量,从而确定参数的个数及其数值。

仍以加法函数为例:

sub add_a_b{
  $_[0]+$_[1];
}

$c=&add_a_b(5,6); #$c的值为11
$d=5*&add_a_b(2,3); #d的值为5*5即25

更为奇特的是,这种方式可以实现变参数传递,即参数个数不确定的传递。C 语言也可以实现这种传递,如我们熟悉的 printf 函数,只是他们的实现机制不太一样,C 更深奥一些,此处就不多解释了。

sub add_all{
  $sum=0; #将sum初始化
foreach $_(@_) { #遍历参数列表
  $sum+=$_; #累加每个元素
}
  $sum; #返回sum即总和的值
}

$a=&add_all(3,4,5); #$a的值为3+4+5即12
$d=2*&add_all(1,2,3,4,5); #d的值为2*15即30





7.4    常用系统调用


下面将介绍一些 Perl 自身提供的一些标准系统函数,这些函数包括: print 、printf 、chop 、split 、keys 、values 、reverse 、sort 、length 、substr 、index 、push 、pop 、unshift 、shift 、join 、grep 、hex 、rand 、localtime 、die 、open 、close 、pack 、read 、exit。下面就来分别介绍他们。


  


指令:print
语法:print Filehandle LIST
说明:这个 Filehandle 可以看作在 I(INPUT)/O(OUTPUT) 之间的一个桥梁,可以利用 FILEHANDLE 来做出数据读入写出的动作。STDIN 是代表从哪里输入数据,例如从电脑的键盘输入;STDOUT是代表从哪里输出数据,例如从电脑的屏幕输出;STDERR 是代表从哪里输出错误的数据,例如从电脑的屏幕输出。而在PERL语言中有三个标准FILEHANDLE:
1. STDIN(标准输入):是代表 STDIN 的 FILEHANDLE
2. STDOUT(标准输出):是代表 STDOUT 的 FILEHANDLE
3. STDERR(标准错误输出):是代表 STDERR 的 FILEHANDLE
如果要使用其他 FILEHANDLE 的时候,就要先用 OPEN 这个函数来打开一个 FILEHANDLE,我们可以用 PRINT 这个函数将 LIST 中的数据输出给 FILEHANDLE。


   语法: print LIST
说明: 如果省略 Filehandle 的话,就会把 Filehandle 默认为 STDOUT。也就是会将 LIST 的数据内容显示在终端屏幕上。


语法: print
说明: 同时省略 Filehandle 和 LIST 的话,就会以 STDOUT 为 Filehandle,并会输出 $_ 这个系统内部变量的数据内容。如果 $_ 变量是一个空字符串的话,就会显示出一个空字符串。



指令: printf
语法: printf Filehandle LIST
说明: 在 Perl 语言中也提代 C 语言中 printf 的语法,用法和 C 语言中的用法一模一样。如果把 Filehandle 省略的话,也一样会把 STDOUT 当成是默认的 Filehandle。
示例:


printf("chomod %d %s\n","711""cgi"); 会将chmod 711 cgi加上换行显示于屏幕上。


指令:chop 语法:chop($url)
说明:把最后一个字符删除。
示例:
$url="www.aka.org.cn/; chop($url);
这时$url="www.aka.org.cn" 还可以简写成 chop($url="www.aka.org.cn/"); chop 函数一般用于去掉从键盘读入数据中的最后一个换行符。


指令:split
语法:split(/pattern/,$text,limit) 其中/pattern/是文字处理的模式,而limit是代表要分割的个数,一般可以省略。
说明:用一个指定的文字处理模式来分割 $text 字符串。
示例:
$text="Michael,Gevin,Mike"; @name=split(/,/,$text); # 这时 @name=("Michael","Gevin","Mike");
@name=split(/,/,$text,2); # 这时 @name=("Michael","Gevin");
在传送CGI应用程序数据的时候会先将数据编码,其中会将FORM中第个数据字段 的数据内容用&这个符号隔开,所以在解码的时候就要以 "&" 这个符号为分割的字符,将每个数据字段分割出。而数据字段的名称和这个数据字段的值是用=这个符号来隔开,如果想取得数据字段的名称和所对应的值的话,就用要 "=" 这个符号来分割数据字段,


指令:keys
语法:keys(%array)
说明:取出关联数组 %ARRAY 中全部的 key。
示例:
%NAME=(1,"mike",2,"michael"); @readkey=keys(%NAMES); # 这时 @readkey=(1,2);


指令:values
语法:values(%array)
说明:取出关联数组 %ARRAY 中全部的 value。
示例:
%NAMES=(1,"mike",2,"michael"); @readval=values(%NAMES); #这时 @readval=("mike","michael");


指令:reverse
语法:reverse(@array)
说明:将数组 @array 中的元素由后到前重新排列。
示例:
@back=("A","B","C","D","E"); @back=reverse(@back); # 这时 @back=("E","D","C","B","A");


指令:sort
语法:sort(@array)
说明:将数组中的元素由小到大排序,如果要由大到小排序的话,要加上reverse这个函数。
示例:
@abc=("d","b","c","a"); @abc=sort(@abc); # 这时 @abc=("a","b","c","d");
@abc=(reverse sort@abc); # 这时@abc=("d","c","b","a"); 这个语法也可以写成 @abc=(reverse sort(@abc));
@number=(5,2,10); @number=sort(@number);
# 上面示例用sort函数来排序数值的时,会出差错,因此要用下面到下面这一句。
@number=(sort{$a<=>$b}@number); # 这时 @number=(2,5,10);


指令:length
语法:length($string)
说明:求出字符串$string的字节(bytes)值。
示例:
$string="erl5"; $size=length($string); # 这时 $size=5;


指令:substr
语法:substr($string,offset,length) offset代表起始字符的位置,length代表引用的字符串长度,如果省略length则代表从起始值到字符串的最后一个字符长度。而offset如果是负值的话,就会从字符串右边开始指定字符。
示例:
$s=substr("perl5",2,2); # 这时 $s="rl";
$s=substr("perl5",2); # 这时 $s="rl5";
$s=substr("perl5",-2,2); # 这时 $s="er";


指令:index
语法:index($string,$substring,position) $substring是要寻找的字符;position代表从哪一个位置开始寻找,假如省略position就从头开始找起。
说明:返回所要找寻的字符在一字符串$string中的位置,如果在字符串中找不到字符的话,则会返回-1这个 值。
示例:
$s=index("perl5","p"); # 这时 $s=0
$s=index("perl5","l",2); # 这时 $s=3
$s=index("perl5","perl"); # 这时 $s=-1


指令:push
语法:push(@array,$string)
说明:在数组@array的最后附加新的元素 ($string)到数组@array中。
示例:
@array=("one","two"); push(@array,"three"); # 这时 @array=("one","two","three")


指令:pop
语法:pop(@array)
说明:将数组(@array)的最后一个元素删除,并将删除的元素返回。
示例:
@array=("one","two"); $rm=pop(@array); # 这时 @array=("one");而$rm="two";


指令:unshift
语法:unshift(@array,$string)
说明:在数组@array的第一个元素前附加新的元素$string到数组@array中。
示例:
@array=("one","two"); unshift(@array,"three"); # 这时 @array=("three","one","two")


指令:shift
语法:shift(@array)
说明:将数组@array的第一个元素删除,并将删除的元素返回。
示例:
@array=("one","two"); @rm=shift(@array); # 这时 @array=("two");而$rm="one";


指令:join
语法:join($string,@array)
说明:在一数组@array的元素之间加上一指定的字符$string,并将结果返回。
示例:
@array=("one","two","three");
$total=join(":",@array); 这时 $total="one:two:three";


指令:grep
语法:grep(/pattern/,@array)
说明:将合文字处理模式(regular expression)的数组元素找出来。
示例:
@array=("one","on","in");
$count=grep(/on/,@array); # 这时 $count=2
@result=grep(/on/,@array); # 这时 @result=("one","on");


指令:hex
语法:hex($string)
说明:将十六进制的数值转成十进制。
示例:
$decimal=hex("ff"); 这时 $decimal=255;


指令:rand
语法:rand($interger)
说明:常和函数srand搭配来取得一随机数,如果没有先宣告stand函数的话,则取出的常数值是一个固定值。这个语法会返回一个介于 0 和$interger之间的数值,如果$interger省略的话,则会返回一个介于 0 和 1 的数值。
示例:
srand; # 要先调用一次srand函数,才能产生随机数的效果
$int=rand(10); # $int的值会大于 0 而且小于 10 ,如果希望产生的乱数是整数的话,就要再加上int 这个函数,如下
$int=int(rand(10)); # $int的值是一个整数,且值在 0 和 9 之间


指令:localtime
语法:localtime(time)
说明:可返回九个有关时间的元素,在写CGI应用程序的时候常会用到系统的时间,所以在此会详细介绍这个函数的用法。
示例:
($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst)=localtime(time);
其中: $sec 代表秒数 [0,59]、$min 代表分数 [0,59]、$hour 代表小时数 [0,23]、$mday 代表是在这个月的第几天 [1,31]、$mon 代表月数 [0,11] 因此要将 $mon 加 1 之后,才能符合实际情况、$year 从 1990 年算起的年数、$wday 从星期六算起,代表是在这周中的第几天 [0-6]、$yday 从一月一日算起,代表是在这年中的第几天 [0,366]、$isdst 只是一个 flag 知道这些变量之后,就可以在 CGI 应用程序中拿来应用了。
此外,也可以用下面这一行指令在 UNIX 系统下取得系统的时间。为了避免错误发生,最好用绝对路径的方法来取得系统时间,如果绝对路径不清楚的话可以用 "which data" 这个指令来得知。$data='/usr/bin/data'; 而在 Perl 5 版本中,也可以用下面这一行指令来取得系统时间。 $data=localtime(time);


指令:die
语法:die LIST
说明:会把LIST字符串显示出来,并退出程序。常常和 $! 这个代表错误信息变量一起使用。
示例:
open(FILE,"$filename")||die "不能打开文件$!\n; # 如果打开文件失败的话,就会显示出错误的信息,之后再退出程序。


指令:open
语法1:open(filehandle,"$filename") 其中 $filename 是一个指定打开的文件名。
说明:这是一个很常用的函数,可用于文件的打开(read only)。
示例:
$filename="usr/abc.txt";
open(FILE,"$filename")||die"不能打开文件$filename\n; #将&ltfile>数据指定给纯变量$line(一行一行地)
while($line=<FILE>)
{
print"$line";
}
close(file); 就会把abc.txt这个文件的内容显示出来。


语法2:open(filehandle,"<$filename")
说明:这个语法也可以打开一个存在的文件(read only)。
示例:
$filesname="usr/abc.txt";
open(file,"<$filename")||die"不能打开文件$filename\n";
@array=&ltfile> # 将 <FILE> 全部的数据内容都指定给数组 @array
close(file);
print "@array"; # 也会把abc.TXT这个文件的内容显示出来。


语法3:open(filehandle,">$filename")
说明:建立一个新的文件(write only);如果已经存在这个文件了,就会把旧文件名覆盖掉。并可用print filehandle的方式将数据存入打开的文件中。
示例:
$filename="/usr/abc.txt";
open(file,">$filename")||die"不能打开文件$filename\n;
print file "this is a new line1\n; # \n是换行字符
print file "this is a new line2\n;
close(file); # 会将数据存在一个新文件中。


语法4:open(filehandle,">>$filename")
说明:数据用附加的方式定入一文件(write only),如果指定的文件名不存在的话就会建立一个新的文件。
示例:
$filename="/path/abc.txt";
open(file,">>$filename")||die"不能打开文件$filename\n";
print file "this is a new line1\n";
print file "this is a new line2\n";
close(file); # 会打数据附加(append)到一个文件(abc.txt)中。


语法5:open(filehandle,"|unix command")
说明:就会把在filehandle的数据输入给unix的指令来作处理。
示例:
$mailprog="/usr/ucb/mail"; # unix系统上的寄信程序(一定要加绝对路径)
$who="mqingyi@126.com";
$open(file,"|$mailprog$who")||die"打开失败\n";
print file "I love you!\n";
print file "I want to see you.\n";
close(file);
该段代码通过 unix 系统的 mail 程序,将 FILE 这个 FILEHANDLE 的数据内容寄给 $who 这个变量所指定的收信人。


指令:close
用法:close(filehandle)
说明:用 open 这个函数来打开一个 filehandle 之后,一定要用 close 批这个函数把所打开的 filehandle 关闭。
示例:
open(filehandle,"$filename");
close(filehandle);


指令:pack
语法:pack("指定的格式",list)
说明:pack这个函数会将一个 list 变成所指定的二进制数据格式。在CGI程序分割解码过程中,会用到 pack 这个函数。
示例:
$string=pack("c",65); #这时 $string="a"; 将65这个ascii码转换成一个unsigned字符,其中c就是指定指转换成 unsigned 字符的意思。


指令:read
语法:read(filehandle,$string,length) 其中 length 是代表读入字符串的长度(bytes)。
说明:用 read 这个函数把 filehandle 中的数据依指定的字符串长度读入之后指派给 $string 这个变量。在cgi程序分割解码过程中,如果 FORM 的传送方式是设定为POST的话,就会将传送的数据设定为标准输入,所以会将数据内容指定给 STDIN 这个标准输入的 filehandle ,而CGI环境变量 $env{'content_length'} 就是代表使用者送出数据内容的长度,因此我们要用 read 这个函数来取得使用者送出的数据内容。
示例:
read(stdin,$buffer,$env{'content_length'}); # 就会将 stdin 这个标准输入 filehandle 中的数据依指定的字符串长度读入,再指派给 $buffer 这个变量。


指令:exit
语法:exit
说明:退出执行的程序。
示例:
print"i love cgi\n"; exit; # 表示显示完 "i love cgi" 以后,将退出这个程序。



  


7.5    文件操作


  大多数 Perl 程序都不是孤立的,它们与环境相互作用。很多的程序也需要通过文件操作实现数据的存贮和交换。文件句柄(file handle)是 Perl 程序中为程序和外部世界提供 I/O 连接的名称。建议在 Perl 程序中文件句柄全部使用大写字母,以示与变量等字符串的区别。特别地,可以将 STDIN/STDOUT/STDERR 也认为是 Perl 的文件句柄,分别代表 标准输入/标准输出/标准错误输出。



打开及关闭文件


       Perl的文件操作与C语言极为相似。如:

         open(FILENAME,"abc.txt");

      该调用为读文件打开,若为写文件而打开,需在文件名前加上大于号:

        open(FILENAME,">abc.txt");

      若要追加至文件尾,可在文件名前加上两个大于号:

        open(FILENAME,">>abc.txt");

      以上三种open()格式在成功时返回真,失败时返回假。但程序中通常没有提示,出错时往往会被人们忽略。 通常当需要给出出错提示时,可加入die()函数。例如:

        open(OUTFILE,">/tmp/outfile")|| die "出错,不能建立/tmp/outfile\n";

      当 open 操作失败时,就会执行 die 给出出错提示。

      对文件句柄的操作完成后,可以用 close 操作符关闭文件。如:

        close(OUTFILE);



文件测试


       Perl的文件操作也可以先测试文件是否存在,是否可读写等,这样操作起来会更安全。如:

         $x="abc.txt";
         if(-e $x) { #abc.txt是否存在?
              # 存在操作
         } else {
              printf "文件不存在。\n";
         }

    -e 操作符用于测试文件或目录是否存在。

      以下为所有文件测试操作符的清单:



文件测试
测试操作符提供的信息


-r
文件或目录可读


-w
文件或目录可写


-x
文件或目录执行


-o
文件或目录归用户所有


-R
文件或目录对真正用户可读


-W
文件或目录对真正用户可写


-X
文件或目录对真正用户执行


-O
文件或目录归真正用户所有


-e
文件或目录存在


-z
文件存在且大小为0


-s
文件或目录存在且不为0(返回字节数)


-f
文件为普通文件


-d
文件为目录


-l
文件为符号链接


-p
文件为命名管道(FIFO)


-S
文件为一个套口(socket)


-b
文件为块特殊文件


-c
文件为字符特殊文件


-t
打开tty控制台的文件句柄


-u
文件或目录是设置用户ID号


-g
文件或目录是设置用户组ID号


-k
文件或目录的sticky位置位


-T
文件是文本文件


-B
文件是二进制文件


-M
以天为单位的存在时间



-A
以天为单位访问时间


-C
以天为单位同代码更改时间


  


删除文件


       Perl的 unlink() 操作符可实现删除文件。如:

         unlink("abc.txt"); # 删除abc.txt



文件重命名


       Perl的rename()操作符可实现文件重命名。如:

         rename("abc","aka") || die "出错,不能更名";

      此时将文件 abc 更名为 aka,成功返回真,否则给出出错提示。



目录操作


       Perl中处理目录非常类似于对文件的处理。

       打开目录句柄:

         opendir(ETC,"/etc")||die "出错,不能打开目录";

      关闭目录句柄:

        closedir(ETC);

      创建目录:

        mkdir("aka",0777)||die "不能创建 aka 目录";

      0777 为文件权限描速数。

      删除目录:

        rmdir("aka") || die "不能删除 aka 目录"。


  


7.6 进程管理


  当你向系统 Shell 发送一个命令行时,Shell 创建一个进程来执行这个命令。这个新进程成为 Shell 的子进程,它的执行不依赖于 Shell 但又与 Shell 相互协调。 同样,Perl程序也能启动新进程。



使用system()和exec()


       生成新进程的最简单的方法就是用 system 操作符。如:

         system("date");

      若要将输出送至now_day文件,则可以:

        system("date>now_day") || die "不能建立now_day文件";



使用单引号


       产生进程的另一方法是将 Shell 命令置于两个单引号之间。如:

         $nowday="现在时间:".'date'

    $nowday 的值为"现在时间:"和date命令的结果的连接。即:"现在时间:Fri Feb 18 23:49:23 PDT 1998"



综合范例


       举一个综合例子,要求从date的输入中分析,周未时打印"周未了,轻松一下",否则打印"努力工作"。简洁的写法为:

         if('date'=~/^S/){
           printf "周未了,轻松一下\n";
         } else {
           printf "努力工作\n"
         }

      date 的输出格式第一个字节为星期,英语中恰好只有周未为 "S" 打头,因此使用了常规表达式判断第一个字符是否为S,即可达到要求。
 楼主| 发表于 2003-9-15 22:16:15 | 显示全部楼层

Perl 的变量

简单变量

数组


关联数组


各种运算符汇总


7.1    简单变量


Perl 的 Hello World 是怎么写的呢?请看下面的程序:


#!/usr/bin/perl
print "Hello World"


这个程序和前面 BASH 的 Hello World 程序几乎相同,只是第一行换成了 #!/usr/bin/perl ,还有显示的时候用的是 print,而不是 echo。有了前面 BASH 基础和 C 语言的基础,许多 Perl 的知识可以很容易的就看懂和记住,下面我们就从简单变量开始。


简单变量是标量,是 Perl 处理的最简单的数据类型。标量可以是数字(如2,3或2.5e6), 也可以是字符串。Perl 中的标量变量以美元符号 "$" 和一个字母开始,后面可以跟字母、数字和下划线,Perl 的变量区分大小写,因此 $a 和 $A 是代表不同的变量。和 BASH 中不同的是 Perl 语言中的变量即使是在最初赋值的时候也必须在变量前面加上 "$" 符号,而且 Perl 不要求 "=" 左右必须没有空格。


虽然 Perl 中和 BASH 一样,没有变量类型的概念,我们还是可以把简单变量分为数值型和字符串型来理解。在赋值时,如果是赋值成字符串,则需要在字符串两边加上双引号(或单引号);如果是数值则就不用了,而且 Perl 中还可以接受8/16(以0开头/以0x或0X开头)进制的整数,还可以接受如 2.5,-6.3e5,-2.3-e6 这样的浮点数。关于简单变量举例如下:


$a=23;
$a = "hello";
$a = 010;(表示十进制的 8)
$a = 0x10;
$a = 0X10;


和 C 语言类似,在双引号之中可以用反斜杠表示一些特殊转义字符,见下表:


结 构
含 义


\n
换行


\r
回车


\t
水平置表符


\f
换页符


\b
退格


\v
垂直置表符


\a
响铃


\e
Esc


\007
任一八进制ASCII值(这里007表示bell)


\x7f
任一十六进制ASCII值


\cC
任一"控制"字符


\\
反斜杠


\"
双引号


\l
下一字母小写


\L
以后所有字母小写直到\E


\u
下一字母大写


\U
以后所有字母大写直到\E


\E
结束\L和\U


另外在 Perl 语言里,我们常会看到 my 这样的变量定义,如:


my $a = "local var";


这表示 $a 是一个程序块的局部变量。





7.2    数组


数组是标量数据的有序列表。数组可以含从 0 个元素大小 直到 你计算机内存可以支持的大小。数组用括号内以逗号分隔的一系列元素来表示。如:


@a=(1,2,3,4,5)
@a=("aka",1974,173.5)


在 Perl 中对数组变量和前面的简单变量的存储是在不同的空间中,对数组的引用需要在变量前加 "@" 符号。


数组的赋值由下面几种用法需要注意:


@a=(1,2,3);
# 初始化一个整数数组。


$a=@a;
# 这里表示将数组 @a 的长度赋给 $a,此时 $a 和 @a 不是一个变量,他们不在一个存储空间里,引用时不会发生混淆。


($a, $b, $c)=(1,2,3);
# 这里表示将 1 赋给 $a;2 赋给 $b;3 赋给 $c;


@a=("a","b","c");
# 初始化一个字符串数组。


@b=@a;
# 表示把数组 @a 拷贝一份给数组 @b,@a 与 @b 不享有共同的存储空间,他们彼此分离。


@c=(@a,@b);
# 表示数组 @c 拥有 @a 和 @b 的所有元素,仍然是一维数组,而不是发生了嵌套。


($a,@b)=@a;
# 表示变量 $a 等于数组 @a 的第一个元素,@b 拷贝了 @a 的剩余元素。


@a=();
# 表示产生或清空一个数组。


($a)=@b;
变量 $a 等于数组 @b 的第一个元素的值。


@b
引用数组 @b 的第 i 个元素。


$b
如果 b 表示一个数组的话,其含义同上。


$a[i,j]=[x,y]
将数组 @a 的第 i 和第 j 个元素赋值为 x 和 y。


@a[i,j]=@a[j,i]
将数组 @a 的第 i 和第 j 个元素的值互相交换。








7.3    关联数组


关联数组是 Perl 语言中特有的一种数据结构,是一个功能强大的数组,他与普通数组的不同在于关联数组不是通过整数下标来索引,而是通过"键值"进行索引。使用关联数组需要在变量前面加上 "%" 号,关联数组的格式如:


ARRAY=(key1,value1,key2,value2,key3,value3);


上面每个 key 都对应着一个 value。关联数组是存在在另外一个存储空间中,不和简单变量以及数组相混淆。


对关联数组的操作有如下规则:

在关联数组中增加、更改一对数据:ARRAY={key}=value; 在关联数组ARRAY中加上一对 key-value,要在关联数组名称前加上 $ 号,而且 key 的名称要在 {} 符号之间,最后再指定 key 所对应的 value 值。如果在这个关联数组中已经有这个 key 了.就会更改这个 key 所对应的 value 。

keys(%array) 操作符可生成由关联数组 %array 中的所有当前关键字组成的列表。即返回奇数号元素(第1,3,5,7...个)的列表。

values(%array) 操作符返回由关联数组 %array 中所有当前值组成的列表,即返回偶数个列表。

echo(%array) 操作符返回由 关键字/值对 构成的元素对列表。对同一数组再进行此操作时返回下一对值直至结束。若没有更多的对时,echo() 返回空表。 (这在打印全部列表中很有用)

删除一对在关联数组中的数据:delete $ARRAY{key}; delete 是 Perl 所提供的函数,作用是删除关联数组中的一个 key 以及这个 key 所对应的 value。使用方法是在 delete 函数之后,指定关联数组中要删除的 key 名称。

下面是一些关联数组操作的例子:


%fred=(one,"aka",two,"free"); $a=$fred{one};
# $a等于"aka"


$b=$fred{two};
# $b等于"free"


$fred{two}="yes";
# %fred=(one,"aka",two,"yes")


@index=keys(%fred);
# @index=(one,two)


@content=values(%fred);
# @content=("aka","yes")


($index,$content)=echo(%fred);
# 此时 $index 的值为 one,$content 的值为 "aka",再执行一次 $index 为值为 two,$name 的值为 "yes"


@a=%fred;
# 将关联数组 fred 指定给数组 a,这时 @a=(one,"aka",two,"yes")


%b=@a;
# 将数组 a 指定给关联数组 b,这时 %b=(one,"aka",two,"yes")


delete $fred{one};
# 将关联数组中 key 值为 one 的一对 key-value 删除,这时 %fred=(two,"yes")


%x=();
# 把 %x 关联数组置空


  


7.4    各种运算符号汇总


赋值(Assignment)运算符
算术(Arithmetic)运算符
数值(Numeric Values)关系运算符
字符串(String Values)关系运算符
逻辑(Logical)运算
其它常用的运算符
常用的文件数据(File Test)运算符


  


赋值(Assignment)运算符




符号
范例
说明


=
$x=$y;
将$x的值指派给$y


+=
$x+=$y;
$x=$x+$y;
将$x加$y之后再指派给$x


-=
$x-=$y;
$x=$x-$y;
将$x减$y之后再指派给$x


*=
$x*=$y;
$x=$x*$y;
将$x乘$y之后再指派给$x


/=
$x/=$y;
$x=$x/$y;
求出$x除以$y之后的商数,再指派给$x


**=
$x**=$y;
$x=$x**$y;
将$x乘上$y次方之后再指派给$x


%=
$x%=$y;
$x=$x%$y;
求出$x除以$y的余数以后,再指派给$x


.=
$str1.=$str2;
$str1=$str1.$str2;
将$str1这个字符串再加上$str2这个字符串之后,再指派给$str1这个字符串


x=
$strx=$y;
$str=$strx$y;
重复$str字符串$y次,并反结果指派给str这个字符串



算术(Arithmetic)运算符

  


符号
范例
说明


+
$z=$x+$y
将$x和$y相加之后,再将结果指派给$z


-
$z=$x-$y
将$x减掉$y之后,再将结果指派给$z


*
$z=$x*$y
将$x和$y相乘之后,再将结果指派给$z


/
$z=$x/$y
将$x除以$y之后,再将商数指派给$z


%
$z=$x%$y
将$x除以$y之后,再将余数指派给$z


**
$z=$x**$y
将$x乘以$y之后,再将结果指派给$z


++
$x++;++$x;
如同$x=$x++1;将$x加一以后再将结果指派给$x


--
$x--;--$x;
如同$x=$x-1;将$x减一以后再将结果指派给$x


.
$z=$x.$y;
将$x字符串和$y字符串连接之后,再将结果指派给$z



数值(Numeric Values)关系运算符




符号
范例
说明


>
$x>$y
如果$x大于$y,返回1的值,否则返回0


>=
$x>=$y
如果$x大于等于$y,返回1的值,否则返回0


<
$x<$y
如果$x小于$y,返回1的值,否则返回0


<=
$x<=$y
如果$x小于等于$y,返回1的值,否则返回0


==
$x==$y
如果$x等于$y,返回1的值,否则返回0


!=
$x!=$y
如果$x不等于$y,返回1的值,否则返回0


<=>
$x<=>$y
如果$x大于$y,返回1的值,如果$x等于$y,否则返回0;&127;如果 $x小于$y,则返回-1的值



字符串(String Values)关系运算符




符号
范例
说明


gt
$str1 gt $str2
如果$str1大于$str2,返回1的值,否则返回0


ge
$str1 ge $str2
如果$str1大于等于$str2,返回1的值,否则返回0


lt
$str1 lt $str2
如果$str1小于$str2,返回1的值,否则返回0


le
$str1 le $str2
如果$str1小于等于$str2,返回1的值,否则返回0


eq
$str1 ep $str2
如果$str1等于$str2,返回1的值,否则返回0


ne
$str1 ne $str2
如果$str1不等于$str2,返回1的值,否则返回0


cmp
$str1 cmp $str2
如果$str1大于$str2,返回1的值,如果$str1等于$str2,返回0,如果$str1小于$str2,则返回-1的值


逻辑(Logical)运算

1) $x && $y(And)


$x    $y    结果


真(True) 真(True) 真(True)


真(True) 假(False) 真(True)


假(False) 真(True) 假(False)


假(False) 假(False) 假(False)


2) $x || $y(Or)


$x    $y    结果


真(True) 真(True) 真(True)


真(True) 假(False) 真(True)


假(False) 真(True) 真(True)


假(False) 假(False) 假(False)


3) $x(Not)


$x    结果


真(True) 假(False)


假(False) 真(True)




其它常用的运算符

指令:..区块运算符(Range Operator)


说明:这个运算符是 Perl 语言中特有的运算符,是一个很实用的运算符。


范例:


@digits=(1..9); # 此时 @digits=(1,2,3,4,5,6,7,8,9);
@digits=('01'..'05'); # 此时 @digits=(01,02,03,04,05);
@char=('A'..'E'); # 此时 @char('A','B','C','D','E',);
@total=(1..3,'A'..'B'); # 此时 @total=(1,2,3'A','B');


指令: 条件运算符(Conditional Operator)


说明: (判别运算式? 运算式1: 运算式2)这个语法的意义和C语言一样:如果判别运算式的值是真(True)的话,则做运算式 1 的运算;如果判别运算式是假(False)的话,则做运算式 2 的运算。


范例:


$price = ($age>60)? 100:200;
如果 $age 大于60的话,则$price等于100,否则$price等于200。




常用的文件数据(File test)运算符




范例
说明


-r $file
如果 $file 是可读取的话,返回 1


-w $file
如果 $file 是可写入的话,返回 1


-x $file
如果 $file 是可执行的话,返回 1


-e $file
如果 $file 存在的话,返回 1


-s $file
返回 $file 的文件大小(bytes)


-f $file
如果 $file 是正常文件的话,返回 1


-T $file
如果 $file 是文本文件的话,返回 1


-B $file
如果 $file 是Binary文件的话,返回 1


-M $file
返回 $file 文件最后一次更改时间到现在的日期数
发表于 2003-9-16 00:56:19 | 显示全部楼层
 楼主| 发表于 2003-9-16 01:05:48 | 显示全部楼层
最初由 tsingson 发表
欢迎访问 http://www.perlchina.net

:thank ,,,我看了看,非常棒的perl中文站点!
谢谢tsingson兄的链接!,,,以后还请多多指教!:thank
 楼主| 发表于 2003-9-19 18:17:56 | 显示全部楼层

请指教

我开始学perl啦~~,不过有个练习我没搞懂~~,
  1. [/home/javalee/myperl]cat lt3-8
  2. #!perl -w
  3. use strict;
  4. print "input you want:";
  5. my $input=<STDIN>;
  6. my @name=qw/com net org gov/;
  7. my $want=&find($input,@name);[color=red]#[/color]这句有问题我感觉 :ask
  8. sub find
  9. {
  10.         my($what,@list)=@_;
  11.         foreach (0 ..$#list)
  12.         {
  13.                 if ($what eq $list[$_])
  14.                 {
  15.                 return $_;
  16.                 print "Found $input\n";print $want;
  17.                 }
  18.         }
  19.         print "No Found it!";
  20. }
复制代码
[/home/javalee/myperl]perl lt3-8
input you want:net
No Found it![/home/javalee/myperl]
我输入的net在@name中是有的呀~~,怎么会提示没找到呢? :ask
请兄弟们指点! :thank
 楼主| 发表于 2003-9-20 21:44:12 | 显示全部楼层

回复: 请指教

最初由 javalee 发表

我输入的net在@name中是有的呀~~,怎么会提示没找到呢? :ask
请兄弟们指点! :thank

问题已经解决
修改后的:
  1. #!perl -w
  2. #
  3. print "input:";[color=blue]
  4. chomp($input=<STDIN>);
  5. my $var=$input;[/color]
  6. my @name=qw{com net org gov};
  7. my $want=&find($var,@name);
  8. sub find  {
  9.         ($what,@list)=@_;
  10.         foreach (0 ..$#list) {
  11.                 if ($what eq $list[$_]) {
  12.                 return $_;
  13.                 }
  14.         }
  15.         "No Found";
  16. }
  17. print "your array is:@name\n$input\'s possion:$want\n";
复制代码
您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表