perl 基本语法介绍

更新时间:2024-03-25 23:48:01 阅读量: 综合文库 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

perl 基本语法介绍

本文介绍从变量类型、操作运算符、控制叙述、子程序、I/O和档案处理、 Regular Expressions、Spectial Variables、Help、函数、总结几个部分介绍perl,只是叙述了一些Perl的基本语法 一.数据类型(Data type):

Perl 的数据类型大致分为四种:Scalar(变量)、Scalar Array(数组)、Hash Array(散列)、References(指针),看起来虽少但用起来却绰绰有余。尤其在写Perl程序时可以不必事先宣告变量,这一点对刚学程序语言的人甚为方便,不过为了以后程序除错和维护方便,我建议你还是养成事先声明变量的习惯比较好。 1 Scalar(纯量变量):

纯量变量是Perl里最基本的一种数据型态,它可以代表一个字符、字符串、整数、甚至浮点数,而Perl把它们都看成是一样的东东! 你甚至可以混着用,不可思议吧。例如: # 井字号开头的后面都是批注。 # 纯量变数以$开头。

# my 是一种宣告变量的方式,它可以使变量区域化。

# 宣告变量时若不加 my 或 local 则Perl会把它当作全域变量使用。 # 习惯上,我们会将字符串用双引号括起来,而数值就不用加引号。 my $x=\ my $x=123; my $x=4.56;

1-1 常用的操作运算符 1)、算术运算符

+(加)、-(减)、*(乘)、/(除)、**(幂)、%(余)、-(负)

(1)求幂(**) 结果不能超出数的范围。当指数为小数时,底数不能为负数,例如:25**1.5=125,(-25)**1.5=?(不成立)

(2)取余(%) 操作数为整数,否则要截取。第二个数不能为0(因为除数不能为0) (3)负(-) -$a=$a*(-1)

此外,注意当一个字符串参加运算,需要转化为整数时,如果不能转化为整数则值为0。例如:'2'+1=3,'a'+1=1 2)、数字比较运算符

<(小于)、=(等于)、>(大于)、==(等于)、<=(小于等于)、>=(大于等于)、!=(不等于)、<=>(比较)

(1)==:比较运算,比较的结果为真或非零,假或零

(2)<=>:比较运算 例如:$a<=>$b,当$a>$b时,值为1;当$a<$b时,值为-1;当$a==$b时,值为0

(3)自动把操作数转化为整数,不能转化为整数则为0

(4)浮点数不精确,不要把值相近的数比较,否则得到的结果是出乎意料的 3)、字符串比较运算符

lt(小于)、gt(大于)、eq(等于)、le(小于等于)、ge(大于等于)、ne(不等于)、cmp(比较)

(1)字符串的比较原则:按照字母表的顺序比较,数字<大写字母<小写字母(a小—z大) (2)字符串比较的次序:字符串从左到右比较。'azz'<‘bc'(即:首先a与b进行比较,然

后z与c进行比较)

(3)当一个串是另一个的前缀时,长度长的为大。例如:dog '123' lt '45' (6)cmp等同于<=>,结果为-1,0, 1

例如:$str1=”a”,$str2=”a“,则print ($str1 cmp $str2) ==> 0 例如:$str1=”a”,$str2=”b”,则print($str1 cmp $str2)===> -1 例如:$str1=”b”,$str2=”a”,则print($str1 cmp $str2)===> 1 (7)空串,0,Undef,这三种情况都为假 例如:如下比较的结果 35 != 30+5 #假 35 == 35.0 #真

'35' eq '35.0' #假(当成字符串来比较) 'fred' lt 'barney' #假 'fred' lt 'free' #假 'fred' eq \ #真 'fred' eq \ #假 ' ' gt ' ' #真

4)、字符串连接(.)、字符/字符串重复(x)

(1)连接( “.“),例如:$a=‘a'.'b'; =>‘ab'

在print时可以直接写print $a$b=>print $a.$b; 但是这两者的原理是不一样的 (2)重复( “x” ),注意:前后有空格(目的:为了和变量名分开),例如:‘a' x 5=‘aaaaa',若重复次数<1,则返回空串 例如:\,即为:\

例如:\,即为:\ 例如:\,即为:\ 例如:6.1 x 3,即为:\

即:左边是一个字符串,右边是该字符串出现的次数

5)、逻辑运算符(&&(and)(与)、||(or)(或)、!(not)(非)、xor(异或) (1)先算左边的值,后算右边的值

(2)&&和and的优先级不同,但除非特殊情况,很难有区别 6)、位操作运算符

&(按位与)、 |(按位或)、 ~(按位非)、 ^(按位异或)、 <<(左移)、>>(右移) (1)操作数为二进制整数,如果是小数则截取为整数 (2)<<左移,移开后空位补0,值为原数值的2*N倍(例如:z<<4,则z=z*(2的4次方)) (3)>>右移,首位补0,值为原值一半(并取整)(例如:z>>4,则z=z/(2的的次方)) 7)、赋值运算符

=、+=、-=、*=、/=、%=、**=、&=、|=、^=、.= (1)$a+=1=>$a=$a+1

(2)可以连等$a=$b=3;=>$a=3;$b=3;

(3)混用 ($a=$b)+=3;=>$a=$b;$a=$a+3;(不建议使用) 8)、自增(++)、自减(--)

(1)不要在变量两边都使用此种操作符:++$var--

(2)不要在变量自增/减后在同一表达式中再次使用:$var2 = $var1 + ++$var1;

(3)可用于字符串的自增,当z、Z、9时进位。$a=‘caz'; $a++; ==> $a=‘cba'; (4)不能用于字符串的自减,当$a--时,按数字运算,字符先转化为0再自减

(5)如果字符串含有非字母数字符号,或数字位于字母中时,自增也先化为0再自增 例如:$a=‘ab*c'; $a++; ==> $a=1; 例如:$a=‘ab5c'; $a++; ==> $a=1;

(6)预增$b=++$a,$a先自增再赋值,后增$b=$a++;$a先赋值再自增;反之,同理 例如:$a=1; $b=++$a; =>$a=2,$b=2; 例如:$a=1; $b=$a++; =>$a=2,$b=1;

(7)只能用于单一变量,不能对运算后的变量进行。例如:($a+$b)++ 9)、逗号(相当于:将两条语句写在一行) 适用范围: 只有当两个语句关联紧密时才使用 例如:$a+=1,$b=$a; => $a+=1; $b=$a; 例如:$a=\10、条件运算符 条件? 真:假

(1)三个操作数:先对条件表达式运算,为真时执行:的左边的运算,为假时执行:的右边的运算

例如:$result = $var == 0 ? 14 : 7; (2)用于简单的条件

(3)条件表达式用在=的左边

例如:$condvar == 43 ? $var1 : $var2 = 14; 例如:$condvar == 43 ? $var1 = 14 : $var2 = 14; 三、操作符优先级别( precedence--优先级)

当一个表达式中出现几种不同的运算符,哪个先计算,哪个后计算 例如:$condvar == 43 ? $var1 : $var2 = 14;(先算条件,后算赋值) 例如:$x = $a == $b;(先算关系,后算赋值)

例如:$x == 0 || $y / $x > 5;(先算除,接着算大于、接着算等于,最后算关系或)

例如:$result = 11 * 2 + 6 ** 2 << 2;(先算幂,再算乘,接着算加,再接着算左移,最后算赋值)

(1)一般的优先级如下:自增自减最高,单操作数高于多操作数,数字运算 > 比较运算(数字比较与字符串比较) > 位运算 > 赋值运算 > 逻辑运算 (2)数字运算:幂 > */>+-

(3)比较运算: <(小于)、>(大于)高于(== 与!=) 2 Scalar Array:

Perl数组变量和列表的概念,列表是包含在括号里的一序列的值,可以为任何数值,也可为空,并且列表存贮于Perl数组变量中,与简单变量不同,Perl数组变量以字符\打头。 Perl数组变量和列表 一、列表

列表是包含在括号里的一序列的值,可以为任何数值,也可为空,如: (1,5.3,\,空列表:()。

注:只含有一个数值的列表(如:(43.2))与该数值本身(即:43.2)是不同的,但它们可 以互相转化或赋值。 列表例:

(17,$var,\

(17,26<<2)

(17,$var1+$var2)

($value,\二、Perl数组--列表的存贮

列表存贮于Perl数组变量中,与简单变量不同,Perl数组变量以字符\打头,如: @array=(1,2,3); 注:

(1)Perl数组变量创建时初始值为空列表:()。

(2)因为PERL用@和$来区分Perl数组变量和简单变量,所以同一个名字可以同时用于Perl 数组变量和简单变量,如: $var=1;

@var=(11,27.1,\

但这样很容易混淆,故不推荐。 1、Perl数组的存取

◆对Perl数组中的值通过下标存取,第一个元素下标为0。试图访问不存在的Perl数组元 素,则结果为NULL,但如果给超出Perl数组大小的元素赋值,则Perl数组自动增长,原 来没有的元素值为NULL。如: @array=(1,2,3,4); $scalar=$array[0];

$array[3]=5;#now@arrayis(1,2,3,5) $scalar=$array[4];#now$scalar=null;

$array[6]=17;#now@arrayis(1,2,3,5,\◆Perl数组间拷贝 @result=@original;

◆用Perl数组给列表赋值 @list1=(2,3,4);

@list2=(1,@list1,5);#@list2=(1,2,3,4,5) ◆Perl数组对简单变量的赋值 (1)@array=(5,7,11);

($var1,$var2)=@array;#$var1=5,$var2=7,11被忽略 (2)@array=(5,7);

($var1,$var2,$var3)=@array;#$var1=5,$var2=7,$var3=\◆从标准输入(STDIN)给变量赋值 $var=;

@array=;#^D为结束输入的符号 2、字符串中的方括号和变量替换

\为Perl数组@var的第一个元素。

\将字符\转义,等价于\,$var被变量替换,[0]保持不变。 \亦等价于\。

\则取消了大括号的变量替换功能,包含文字:${var}. 3、列表范围:

(1..10)=(1,2,3,4,5,6,7,8,9,10) (2,5..7,11)=(2,5,6,7,11) (3..3)=(3)

◆用于实数

(2.1..5.3)=(2.1,3.1,4.1,5.1) (4.5..1.6)=() ◆用于字符串

(\@day_of_month=(\◆可包含变量或表达式 ($var1..$var2+5) ◆小技巧: $fred=\

print((\其结果为: Hello,Fred! Hello,Fred!

4、Perl数组的输出: (1)@array=(1,2,3); print(@array,\结果为: 123

(2)@array=(1,2,3); print(\结果为: 123

5、列表/Perl数组的长度

当Perl数组变量出现在预期简单变量出现的地方,则PERL解释器取其长度。 @array=(1,2,3);

$scalar=@array;#$scalar=3,即@array的长度

($scalar)=@array;#$scalar=1,即@array第一个元素的值 注:以Perl数组的长度为循环次数可如下编程: $count=1;

while($count<=@array){

print(\$count++; }

6、子Perl数组 @array=(1,2,3,4,5);

@subarray=@array[0,1];#@subarray=(1,2) @subarray2=@array[1..3];#@subarray2=(2,3,4)

@array[0,1]=(\@array[0..3]=(11,22,33,44);#@array=(11,22,33,44,5)now @array[1,2,3]=@array[3,2,4];#@array=(11,44,33,5,5)now @array[0..2]=@array[3,4];#@array=(5,5,\可以用子Perl数组形式来交换元素: @array[1,2]=@array[2,1];

7、有关Perl数组的库函数 (1)sort--按字符顺序排序

@array=(\

@array2=sort(@array);#@array2=(\@array=(70,100,8);

@array=sort(@array);#@array=(100,70,8)now (2)reverse--反转Perl数组 @array2=reverse(@array); @array2=reversesort(@array); (3)chop--Perl数组去尾

chop的意义是去掉STDIN(键盘)输入字符串时最后一个字符--换行符。而如果它作用到Perl数组上,则将Perl数组中每一个元素都做如此处理。 @list=(\

chop(@list);#@list=(\(4)join/split--连接/拆分

join的第一个参数是连接所用的中间字符,其余则为待连接的字符Perl数组。 $string=join(\结果为\@list=(\

$string=join(\结果为\@array=split(/::/,$string);#@array=(\3 Hash Array(Associative Array): perl hash 常见用法 基本用法

# 初始化 %h为空数组%h = {};# 用数组初始化%h为 a=>1, b=>2%h = ('a', 1, 'b', 2);# 意义同上,只是另一种更形象化的写法。%h = ('a'=>1, 'b'=>2);#如果key是字符串,可以省略引号。下面这行和上面那行是一样的%h = (a=>1, b=>2);# 用{}来访问print \# 打印1$h{b} = '2b';print \打印2b# 删除key用deletedelete $h{b}; # 从$h删除'b' 清空hash undef %h

得到hash的所有键值

# 得到所有keys,顺序取决于hash函数,或者说是乱序 @all_keys = keys %h;

# 所有键值,是按hash的值从大往小排列的。值的比较是数字比较(比如说,10>9) @all_keys = sort{$h{$b}<=>$h{$a}} (keys %h);

# 所有键值,是按hash的值从小往大排列的。值的比较是数字比较 @all_keys = sort{$h{$a}<=>$h{$b}} (keys %h);

# 所有键值,是按hash的值从小往大排列的。值的比较是字符串比较(比如说,'10' < '9') @all_keys = sort{$h{$a} cmp $h{$b}} (keys %h); 判断hash是否包含key exists($h{$key}); Hash的长度

想要知道一个hash存放多少数据 $hash_size = keys %h

# 把%h的长度放到$hash_size中

print scalar kes %h, \

# 打印%h的长度。这里用了scalar来返回数组长度。 遍历一个hash

while (my ($k, $v) = each %h) {print \Reference引用

Reference类似于C/C++的指针 $h_ref = \\%h;

# 获得一个hash的reference%aHash = %{$h_ref};

# 把hash reference当成hash用$value = $h_ref->{akey} # 这个和%h{akey}是一样的 传递hash到函数

一般都是传递一个reference到函数

%h = ();$h{a}=1;foo(\\%h)print $h{b}, \ # 打印出2。

这个值来自于函数foo() sub foo {my ($h) = @_;print $h->{a}, \ # 打印出1$h->{b} = 2;}

函数返回hash,或者hash引用(hash reference) 函数可以返回hash

sub foo {my %fh;$fh{a} = 1;return %h;} my %h = foo();print 二 控制结构(Control Statements) 1 选择 if结构

Perl的条件控制叙述和C语言很像,让使用者很快就能掌握它。不过Perl比C语言又另外多了些实用的语法,我用底线标出来,大家一看便知。

# Expression 就是条件叙述式,Perl和C一样没有定义布尔数据型态(Boolean datatype), # 因此 0 是false、非0 是ture。另外要注意字符串运算子和数值运算子要分清楚哦。 # Code Segment 就是用大括号括起来的一堆指令,也就是一个Block。 if (Expression) {Code Segment}

if (Expression) {Code Segment} else {Code Segment}

if (Expression) {Code Segment} elsif (Expression) {Code Segment} else {CodeSegment} # elsif 就是 else if

# 如果指令(statement)只有一项,我们可以使用倒装句法,看起来比较简洁。 statement if (Expression); # unless 就是if not

statement unless (Expression);例:

print \ $x-=10 if ($x == 100);

看吧! C 语言有的Perl大部分都有,学过 C 的人可以毫不费力的学会Perl。 2循环结构

Perl的循环控制叙述也和C语言很像,当然,照例Perl也另外多了些实用的语法: # 注意:纯量变数前面要加个 $ 字号,这一点和C语言不一样哦。 for($i=0; $i<=10; $i++) {Code Segment}

# foreach 是承袭UNIX的shell script来的,

# 第一个自变量是纯量变数,第二个自变量要用括号括起来,里面是一个纯量数组, # 顾名思义它就是把数组中的每个元素依序传给第一个自变量,直到全部传完。

# 它和 for($i=0; $i<=$#array; $i++) 用法虽然不同,但目的都是要取出数组的每个元素。 foreach $i (@array) {Code Segment}

# 其实在Perl中,for和foreach是可以混着用的,就看个的人习惯了。 # 下面这行就等于上面第一个叙述,不过简洁多了,大家可以试着用用看。 for $i (0..10) {Code Segment} # while控制循环和后置循环。 while($i<=10) {Code Segment}

do {Code Segment} while(Expression);

# Perl也有和C语言的break和continue一样的指令,Perl叫它做 last 和 next (较口语化)。 # last是跳出现在所在的循环,next则是跳过下面的指令直接执行下一次的循环。 while(chomp($i=)) { next if ($i == 5); last unless ($i > 10); }

Perl 还有提供label(标记)的语法,也就是goto 指令,不过有经验的programer并不喜欢用它,我也不建议大家使用,所以就此按下不讲。有兴趣的人请自行查阅。还有一点值得注意的是Perl没有提供像C语言一样的 switch 叙述,不过Perl的pattern match的功能非常强,所以我建议你直接用 if else 叙述来做就好了。 3子程序(Subroutines)

(a) Syntax: sub NAME {Code}

(b) 呼叫子程序: &NAME(para1, para2,...) (c) 参数传递:@_

Perl 和C一样是采用Call by value的方式,不过因为Perl不用事先宣告变量,所以建立子程序的时候也不用宣告要传递什么参数。当主程序在传递参数给子程序时,Perl会把括号括起来的参数按顺序放在一个特殊的全域变量 @_ 数组中,然后子程序就可以随意使用数组 @_ 里的参数,例如 $_[0] 是第一个参数, $_[1] 是第二个,或是用 my($a1,$a2,$a3,...) = @_;来取出各个参数,当然 my @arg=@_; 或 my %arg=@_; 也是可以的。由于Perl的语法非常活泼,使得程序在维护时特别棘手,因此写批注成为一项很重要的工作。我建议你最好在每个子程序前面加上对这段子程序的描述,特别是需要传递的参数要注明清楚。 (d) Variable Localization:my or local

通常我们在程序中定义的变量都是全域变量,所以在子程序中若要把变量区域化则要加上 my 或 local 关键词,例如:my $x=3;,若子程序所用的变量名不小心和主程相同,Perl会以目前正在执行的子程序里的变量为优先。 4 I/O和档案处理 (a) Syntax:

open(FILEHANDLE,\ close(FILEHANDLE);

这里的Expression是一个叙述加上文件名称,若Expression只有文件名称没有加上叙述,则预设是只读。Expressions叙述如下: Expression Effect open(FH, \ open(FH, \

open(FH, \ Opens filename for writing.

open(FH, \ Opens filename for both reading and writing.

open(FH, \ Appends to filename.

open(FH, \ Runs the command and pipes its output to thefilehandle. open(FH, \ Pipes the output along the filehandle to thecommand. open(FH, \ Opens STDIN. open(FH, \ Opens STDOUT.

open(FH, \ open(FH, \ Where N is a number, this performs the equivalent of C'sfdopen for writing. 例:

# 开启$filename这个档案,若开启失败则印出die后面的讯息,并结束程序。 open(FILE, $filename) || die \

# 下面是一个十分精简的写法,和 while($_=){print \是等效的。 print while();

# 档案开启后要记得随手关闭,这才是写程序的好习惯。 close(FILE);

# $!和$_都是Perl的特殊变数,下面会介绍的。 (b) Input:

Perl没有特别用来输入的函数,因为Perl在执行程序时,会自动开启标准输入装置,其filehandle定为STDIN,所以在Perl中要输入数据的方法就是使用:

# Perl不会自动去掉结尾的CR/LF,跟C语言不同,所以要用chomp函数帮你去掉它。 # 大家常常会忘记这个动作,导致结果跟你想的不一样,要特别注意一下。 $input=; chomp $input; # 下面是较简洁的写法。 chomp($input=);

(c) Output:print \字符串\

Perl也有printf()函数,语法和C语言一模一样,我就不多做介绍了。Perl另外有个print函数,比printf()更方便、更好用,包你爱不释手。Output不外乎是输出到屏幕或档案,用例子来说明比较容易了解。

# 不用再指定变量的data type,这样不是比printf()方便多了吗? print \

# . 是字符串加法的运算子,上下这两行是等效的。 print \# 输出到档案的方法。 print FILE \

# 下面是print的特殊用法,学自shell script的用法: print

这招叫做 here document,XXX可以是你取的任何标识符,在标识符之间的字都会按照你所写的样子输出,就像\\标签一样。而当一行的开头是XXX你取的这个标识符时,才会停止输出。 XXX

Perl 也有和 C 一样以 \开头的特殊字符: \\t tab

\\n newline \\r return \\f form feed

\\b backspace \\a alarm(bell) \\e escape \\033 octalchar \\x1b hex char \\c[ control char

\\l lowercase next char \%u uppercase next char \\L lowercase till \\E \\U uppercase till \\E

\\E end case modification

\\Q quoteregexp metacharacters till \\E

另外需要说明的是 Perl 融合了unix shell script的使用惯例,以双引号(\括起来的字符串会先经过展开,但反斜线(\\)后面的字符则不展开,当作一般字符看待。而以单引号('')括起来的字符串完全不会展开,以反单引号(``)括起来的字符串会把它当作命令列指令一样执行,等于system()一样。初学者常常会搞混,但习惯之后就会觉得不这样分清楚反而不行哩,举个例吧: $x=\

print \ # Output ls -l print \ # Output $x print '$x'; # Output $x

print `$x`; # Output files in this directory 函数

1. Perl函数 通过 & 调用. 2. Perl参数

Perl天然支持可变数目个参数。

在函数内部,所有参数按顺序放在数组 @_ 中,在函数内部,$_[0] 表示函数的第一个 参数,其余类推。 3. shift

shift 后跟一个数组,表示将数组的第一个值返回。数组也被改变,其第一个元素被弹 出。

演示代码一(求最大值): #!/usr/bin/perl -w use strict;

# 调用函数max,取得一组数值的最大值,并输出。 my $maxCnt = &max(11,22,33); print \sub max {

# 采用遍历算法。先将参数中的第一个值赋给$currentMaxCnt。 # @_ 是默认的包含本函数所有参数 [如(11,22,33)]的数组。

# shift @_ 有两个结果: 1. 将数组 @_ 中的第一个值做为返回值(赋给了 $currentMaxCnt). 2. 将@_数组第一个值弹出[此后@_的值变为(22,33)]. my $currentMaxCnt = shift @_;

# 函数中使用shift时,@_可以省略。上面代码也可以写成这样。 # my $currentMaxCnt = shift; # 遍历整个@_数组。 foreach ( @_ ) {

# $_ 表示数组@_中当前被遍历到的元素. if ( $_ > $currentMaxCnt ) {

# 如果发现当前数组元素比$currentMaxCnt大,那就将$currentMaxCnt重新赋值为当前 元素。

$currentMaxCnt = $_; } }

# 函数返回值为标量$currentMaxCnt. return $currentMaxCnt; }

演示代码二(求和): #!/usr/bin/perl -w use strict;

# 求一组数的和并打印。 my $s1 = &sumvar(11,22,33); my $s2 = &sumarg(22,33,44);

my $s3 = &sumgod(11,22,33,44,55); print \# 办法1 sub sumvar {

# 将参数数组的前三个元素值相应地赋给($first, $second, $third) (my $first, my $second, my $third) = @_;

# 返回其和值。缺点: 如果是求四个参数的和,依然只能给出前三个的和。 return $first + $second + $third; }

# 办法2 sub sumarg {

# $_[0] 表示参数数组@_的第一个元素。其余类推。 my $first = $_[0]; my $second = $_[1]; my $third = $_[2];

# 返回其和值。缺点: 同sumvar. 只是通过这里学习 $_[0] 这种用法。 return $first + $second + $third; }

# 办法3, 参数可以任意多。都能求其和。 sub sumgod{ my $s = shift @_; foreach ( @_ ) { $s = $s + $_; }

# 同前面函数max。 return $s; }

8总结

整理了一下自己觉得用的比较多的一些符号、用法、函数、库之类的,这些都是很基本 的,但是“背熟”了,对提高效率会很有帮助。 数据操作

* $ - 声明与引用用一个scalar的变量

* @ - 声明与引用一个list,但是当访问一个list的成员时,需使用$ListName[index] * % - 声明与引用一个hash表,但是当访问一个hash的成员时,需要使用$HashName {key}

特殊变量

* $0 - 当前运行脚本的文件名

* @ARGV - 当前运行脚本的命令行参数列表 * $_ - 默认变量,如循环中的当前变量 * @_ - 函数的输入参数列表 * %ENV - 系统的环境变量

* @INC - Perl的Include路径列表,我们可以往该列表中添加我们自己的目录来方便引 用自定义的库

* $! - 当前系统提示,错误信息 * $^O - 操作系统的名字

* STDIN,STDOUT,STDERR - 输入输出的默认句柄,可以作一定的自定义 * => - 声明一个hash时可以用来明确的表示出key=>value的对应关系

* $^I- 指定备份的文件的后缀名,如此,被修改的文件将会自动以该后缀名保存一个副 本

特殊用法

* &Sub - 调用一个函数,虽然Perl有些规则让你在某些时候可以省略这里的&符号,但 是处于一致性考虑,所以自定义的函数的调用,我一律采用此种方式。

* $# - 用来取得模个数组的最大index, 一般情况下,也可以用-1来表示最后一个元素 的index的

* qw() - 快速声明一个字符串数组,可以省略那些烦人的引号 正则表达式

* $ - 获取被括号捕获的匹配

* $`, $&, $' - 获取匹配的字符串,以及其前后两个部分 * ^,$ - 字符串的始末位置,用作定位 常用函数

* pop, push, shift, unshift, reverse - list的操作函数 * keys,values, exists, each, delete - hash的操作函数 * chomp, split, join, index, substr, sort - 字符串操作函数 * sprintf,printf, print - 格式化输出函数 * system, exec, `` - 系统命令调用函数

* glob, unlink, mkdir, rmdir, rename,chmod,chown, open, close, opendir, closedir - 文件系统操作函数

* stat, lstat,localtime,gmtime,utime - 文档属性,时间相关函数

* hex, oct - 二进制,八进制,十六进制数转化成十进制的函数 * grep, map - list高级操作函数

这些函数的详细介绍,都可以通过命令: #perldoc -f functionname 查到 常用库

* File::Basename - 根据path获取文件名或者文件路径 * File::Spec - 根据文件名与路径组合成全路经 * File::Find - 递归遍历某个目录下所有文件

* XML::Simple - 以一个复杂的结构来表示xml文件,使用起来相当方便 * Time::HiRes - 经常用来计算一个操作所耗费的时间

* Getopt::Long - 当脚本需要复杂的输入参数与选项时用到 * Cwd - 拿到当前工作目录 * IO::File - 文件操作

* Win32 - 当需要调用一些Windows API时我会用它

详细说明什么是Perl

作者: 字体:[增加 减小] 类型:转载

一、Perl是什么?

Perl是Practical Extraction and Report Language的缩写,它是由Larry Wall设计的,并由他不断更新和维护,用于在UNIX环境下编程。

.Perl具有高级语言(如C)的强大能力和灵活性。事实上,你将看到,它的许多特性是从C语言中借用来的。

.与脚本语言一样,Perl不需要编译器和链接器来运行代码,你要做的只是写出程序并告诉Perl来运行而已。这意味着Perl对于小的编程问题的快速解决方案和为大型事件创建原型来测试潜在的解决方案是十分理想的。

.Perl提供脚本语言(如sed和awk)的所有功能,还具有它们所不具备的很多功能。Perl还支持sed到Perl及awd到Perl的翻译器。

简而言之,Perl象C一样强大,象awk、sed等脚本描述语言一样方便。 二、Perl在哪里?

Perl通常位于/usr/local/bin/perl或/usr/bin/perl中。你可以在Internet用匿名FTP免费得到它,如ftp://prep.ai.mit.edu/pub/gnu/perl-5.004.tar.gz。 安装过程为: (1)解压:

$gunzip perl-5.004.tar.gz $tar xvf -

将编译生成的可执行文件拷贝到可执行文件通常所在目录,如: $copy /usr/local/bin/perl 注:这需要系统管理员权限。

北美 地址 ftp.netlabs.com 目录 IP地址:192.94.48.152 目录 /pub/outgoing/perl5.0 ftp.cis.ufl.edu IP地址: 128.227.100.198 目录 /pub/perl/src/5.0 ftp.uu.net IP地址: 192.48.96.9 目录 /languages/perl ftp.khoros.unm.edu IP地址: 198.59.155.28 目录 /pub/perl ftp.cbi.tamucc.edu IP地址: 165.95.1.3 目录 /pub/duff/Perl ftp.metronet.com IP地址: 192.245.137.1 目录 /pub/perl/sources genetics.upenn.edu IP地址: 128.91.200.37 目录 /perl5 欧洲 Site Location ftp.cs.ruu.nl IP地址: 131.211.80.17 目录 /pub/PERL/perl5.0/src ftp.funet.fi IP地址: 128.214.248.6 目录 /pub/languages/perl/ports/perl5 ftp.zrz.tu-berlin.de IP地址: 130.149.4.40 目录 /pub/unix/perl src.doc.ic.ac.uk IP地址: 146.169.17.5 目录 /packages/perl5 澳洲 Site sungear.mame.mu.oz.au Location IP地址: 128.250.209.2 目录 /pub/perl/src/5.0 南美 Site ftp.inf.utfsm.cl Location IP地址: 146.83.198.3 目录 /pub/gnu 三、运行

用文本编辑器编辑好你的Perl程序,加上可执行属性:$chmod +x 就可以执行了:$./。如果系统提示:\,则说明你没有安装成功,请重新安装。

注:你的程序的第一行必须为#!/usr/local/bin/perl(perl所在位置)。 四、注释:

注释的方法为在语句的开头用字符#,如: # this line is a comment

注:建议经常使用注释使你的程序易读,这是好的编程习惯。

不错的mod_perl编程的简单应用实例介绍

作者: 字体:[增加 减小] 类型:转载 介绍性指南

mod_perl 是个庞大而复杂的工具,它内建了许多模块帮助你方便地构建动态网站。这篇指南的目的是帮助你构建一个良好的 mod_perl 模块,并从中理解 mod_perl 的实现技术。我并不推荐使用这里介绍的技术来建立一个大型站点,尤其对于一个刚刚涉足 mod_perl 的人来说。但我推荐大家可以深入看一下它的一些内建的方案,比如 Mason, AxKit, EmbPerl,

Apache::ASP 和 PageKit 等等。 你需要什么?

本指南假设你已经有过安装和测试 mod_perl 的经验。以及较新版本的 Apache 的安装经验。因为有可能你需要在你的机器上实现时适当的修改本文提供的配置。我们需要你安装一些模块并且需要进入 Apache 的配置目录作修改。所以最好你有 root 权限来做这些事情。当然你还需要一个文本编辑器。 切入正题

mod_perl 模块也是 Perl 模块,但它有较为特别的设计。最方便的创建一个 Perl 模块的方法就是使用标准的 Perl 分发自带的工具 h2xs 。你可以在命令行模式键入 h2xs 来看看它的参数列表。现在,到一个适当的目录开始一个新项目,键入:h2xs -AX -n Apache::Tutorial::Firsth2xs 将会创建目录 Apache,以及其他一些子目录.现在进入最深一级的目录看看:cd Apache/Tutorial/First在这个新目录里面,你可以看到 6 个文件: README, Changes, First.pm, MANIFEST, Makefile.PL 和 Apache-Tutorial-First.t。它们的作用如下: README

这个文件包含一些安装信息,模块依赖性,版权信息等 Changes

这个文件作为你的项目的修改日志(changelog)文件 First.pm

这是主模块文件,包含你的 mod_perl 句柄代码(handler code)。 MANIFEST

本文件用于自动构建 tar.gz 类型的模块版本分发。这样你就可以把你的模块拿到 CPAN 发布或者分发给其他人。它包含了你在这个项目中所有文件的列表。 Makefile.PL

这是标准的 Perl Makefile 构造器。用于创建 Makefile.PL 文件来编译该模块。 Apache-Tutorial-First.t

针对该模块的一些测试脚本。默认情况下它只是检查模块的载入,你可以添加一些新的测试单元。好了,现在我们开始把First.pm变为可工作的mod_perl模块。使用文本编辑器打开该文件,修改后的内容如下: package Apache::Tutorial::First; use strict;

use vars qw/$VERSION/; use Apache::Constants; $VERSION = 0.01; sub handler { my $r = shift;

$r->send_http_header('text/html'); print

\ return OK; } 1;

不要忘记文件末尾的”1;”,对于Perl来说,一个模块最后返回的非零值表示该模块已经被成功编译。 安装你的模块

h2xs 工具使我们的模块安装工作极为方便。在和你的 First.pm 文件相同的目录中。键入: perl Makefile.PL make

make test如果 make test 成功的话,你需要以 root 身份执行:

make install这样你就把你的模块安装到了 perl 的库目录(library directory)。 添加该模块为 Apache 的一个句柄(handler)

现在我们需要进入 Apache 配置目录来修改配置文件,使我们的模块作为 Apache 内容处理阶段的处理器。打开 httpd.conf 文件,在末尾加入如下配置: SetHandler perl-script

PerlHandler Apache::Tutorial::First

然后保存配置文件,并且重新启动 apache 服务器: apachectl stop

apachectl start现在使用浏览器访问http://localhost/mod_perl_tutorial,你将如期的看到显示 “Hello World” 页面。

当 Apache 启动的时候,它读取它的配置指令并把适当的命令传递给相应的处理该命令的模块。这里有两个相关的指令 SetHandler 和 PerlHandler。

第一个指令 SetHandler 由 mod_mime 模块处理,该指令表示使用什么模块作为处理请求的主要部分。这里所设置的perl-script 表示使用 mod_perl 来处理请求。

第二个指令PerlHandler由mod_perl模块来处理,它只是简单的说明使用我们的模块来处理请求的主要部分。有一点需要注意,无论何时在你有一个 PerlHandler 时,你需要相应的 SetHandler perl-script 配置指令。这样才能使你的 mod_perl 代码起作用。我总是认为这是一个弱点,但这将涉及 Apache 内部的处理机制,所以在将来这也很难改变。

现在请求来了,Apache 查看用什么模块来处理相应的 URI 并且在这里决定使用 mod_perl,而 mod_perl 知道它必须把请求发送给我们的模块,并调用我们模块的 handler() 函数作为 Apache::Request 对象的第一个参数。而我们的 handler() 函数的返回值决定了下一步 Apache 将要做什么。现在我们知道返回值 OK 意味着一切成功。 OK是个从Apache::Constants 模块导出的常量。 调试

如果你没有看到 “Hello World”, 那你可能看到了一个错误页面,或者其他什么完全不同的。第一步去查看错误日志看看到底是什么发生了错误。我习惯于在浏览器中请求后立即查看错误日志。你可以使用 tail 工具:tail -f /path/to/apache/logs/error_log(使用你的真实 error_log 路径替换上面的路径。如果你不肯定它在哪里,查看你的 httpd.conf 文件的 ErrorLog 指令部分)

现在重新载入页面,然后 error_log 将告诉你什么地方出现了问题。更多的关于 perl 调试,请参见 perldebug. 加入更多

现在如果你想要针对上面的情况作一些修改,该如何做呢?不幸的,唯一一种安装模式如下: 修改你的 First.pm 文件

重新以 root 身份运行 make install 重新启动 Apache

这也许很麻烦,特别是重新启动 Apache。针对这个问题,我们可以另外安装一个特别设计的模块来避免每次这样麻烦的做。首先你需要从 CPAN 下载并安装 Apache::Reload 模块(除非你已经使用 mod_perl 1.26 或者更高版本)。在这里

http://search.cpan.org/search?dist=Apache-Reload 下载。 解开 tar.gz 文件并进入新目录,执行: perl Makefile.PL

make然后到 root 身份执行:

make install现在再次打开 httpd.conf 文件,加入:

PerlInitHandler Apache::Reload这将测试所有有所改变的模块并在必要时自动重新载入新模块。这对于开发来说很有用,但会有性能损失,所以在开发完成之后,就将该特性关闭。 阅读更多

从这里开始你有很多事情需要去做。Apache API 本身就十分庞大,大多数都可以通过 perldoc Apache 看到相应的文档. 现在这个模块基本上没有什么价值,因为只有一个 URI 可以用于被该模块所控制(http://server/mod_perl_tutorial),这使得它变得不够灵活。为了使一个模块可以处理多个 URI ,有许多解决办法,但最好的还是推荐使用 Apache::Dispatch 模块。

可以在 CPAN 下载 http://search.cpan.org/search?dist=Apache-Dispatch. Apache::Dispatch 允许你保留标准的 mod_perl handler构架,同时还允许多个函数和多个URIs 被派发。 接下来我不建议象例子中一样直接向浏览器输出内容。请考虑使用一些常用的模版技术,比如 Template-Toolkit, HTML::Template, 更甚于使用 XSLT 或者 XPathScript (有很多很多这样的模版技术可选,我们希望有一天可以有文章来讨论这些技术来帮助你来选择)。

不错的一篇学习CGI脚本(脚本)

作者: 字体:[增加 减小] 类型:转载

学习CGI脚本(脚本)

CGI 意思为 Common Gateway Interface, 一种基于浏览器的输入、在Web服务器上运行的程序方法. CGI脚本 使你的浏览器与用户能交互,为了在数据库中寻找一个名词, 提供你写入的评论,或者从一个表单中选择几个条目并且能得到一个明确的回答. 如果你曾经遇到过在web上填表或进行搜索, 你就是用的CGI脚本. 你那时也许没有意识到,因为大部分工作是在服务器上运行的,你看到的只是结果.

作为一个网页设计者, 你创建客户端的 CGI脚本, 服务器端的程序用来处理用户输入, 结果返回给用户.

在这里你将学习关于CGI脚本的一切: CGI脚本是什么?它是怎样工作的 一个CGI脚本输出象什么?

怎样用参数或无参数创建一个CGI脚本 怎样创建一个返回规定响应的CGI脚本 怎样创建一个输入表单的CGI脚本 有关在使用CGI脚本中的问题 你能在脚本中使用的CGI变量 本章节假设在UNIX系统下的。 CGI脚本是什么?

CGI脚本简单地讲是个运行在Web服务器上的程序, 有浏览器的输入触发. 这个脚本通常象服务器和系统中其他程序如数据库的桥梁。

CGI 脚本难道不是一个真正的脚本?按照你的服务器的支持, 他们可能是一个编译好的程序或者批命令文件或者其他可执行的东西. 为了简单起见,我们统称他们为脚本scripts.

CGI 脚本是任何运行在web服务器上的程序. CGI意思是Common Gateway Interface。 CGI脚本是用下列两种方法使用的: 作为一个表单的ACTION 或 作为一个页中的直接link。

CGI脚本是怎样工作的?

CGI脚本有服务器调用, 基于浏览器的数据输入. 图1 显示在浏览器、服务器和脚本之间是怎样的一个流程.

图1. 从浏览器到服务器到脚本到程序 记住再回来噢! 这有个简短的示意解释:

一个URL指向一个CGI脚本. 一个CGI脚本的URL能如普通的URL一样在任何地方出现。 服务器接收请求, 按照那个URL指向的脚本文件(注意文件的位置和扩展名),执行脚本. 脚本执行基于输入数据的操作,包括查询数据库、计算数值或调用系统中其他程序. 脚本产生某种Web服务器能理解的输出结果.

服务器接收来自脚本的输出并且把它传回浏览器,让用户了解结果。

一个简单的例子

这里详细一步一步地解释所有有关发生的细节。 在图2中有个例图:

图2. 带有一个脚本连接的页.

Display Date处是个指向CGI脚本的连接. 它的HTML是这样的:

说明是个CGI脚本是因为这里面有个cgi-bin的路径. 在许多服务器cgi-bin是仅能够放置CGI脚本的目录.

当你选择这个连接时, 你的浏览器将向www.popchina.com服务器提出请求. 服务器接收这个请求计算出URL处的脚本文件名然后执行这个脚本. 这个getdate脚本, 在UNIX系统中执行是这样的: #!/bin/sh

echo Content-type: text/plain echo

/bin/date

第一行是个特殊的命令,告诉UNIX系统这是个shell脚本; 真实的情况是从这行开始的下一行,这个脚本做两件事:它输出行Content-type: text/plain, 接着开始一个空行;第二, 它调用UNIX系统时间date程序, 这样输出日期和时间. 脚本执行后输出应该这样: Content-type: text/plain

Tue Oct 25 16:15:57 EDT 1994

这个Content-type是什么东东?它是个特殊的编码,Web服务器用来告诉浏览器输出这个文本是什么类型的. 这与HTML中Content-type含义是一样的。

这样浏览器的输出就如图3. 图3 date脚本输出结果.

这是最基本的,实际情况要复杂得多,总之可以用来理解浏览器、服务器和脚本之间是怎样工作的。

我能用CGI脚本吗?

在你使用CGI脚本之前,有两件事你也许要解决:CGI脚本 是个高级的Web特性并且需要你和Web 服务器管理者一样好的知识。

肯定吗?就是做不到,学学也可以?好吧!让我们继续. 你的服务器配置允许CGI脚本吗?

为了能写和运行CGI脚本, 你需要一个Web服务器. 不象通常的HTML文件, 你不能在本地系统上写或试验你的CGI脚本; 你得通过Web服务器来做这个.

但是即使你有一个Web服务器, 这个服务器必须特别地为运行CGI脚本配置一下. 那意味着你所有的脚本必须放置在一个叫做cgi-bin的目录下.

在编写CGI脚本之前, 询问你的服务器管理者是否允许你安装和运行CGI脚本, 并且如果可以的话,他们必须放置在哪儿?还有,你必须有个真正的Web服务器,如果是FTP或Gopher服务器,那你就不能用CGI.

如果你在自己的服务器上运行, 你必须特别地创造一个叫cgi-bin的目录,并配置你的服务器认可这个目录为一个脚本目录. 也必须记住下面有关CGI脚本特点:

每个脚本是个程序, 它运行在浏览器可以请求的系统上, 执行时使用CPU时间和内存. 如果有成打上千的这些脚本同时运行,会怎样?你的系统将不忍负载直至崩溃。

如果你不仔细地编写你的CGI脚本, 你将有可能让别人通过你的CGI脚本参数进入伤害你的系统.

你会编程吗?

初学者注意! 一般地, 你必须具备一些基本编程概念与方法。你必须有类似系统工作的经验。如果你没有这些背景, 你必须去学习,好了,费话不多说. 你必须用什么编程语言?

你可以用你熟悉的任何语言编写CGI脚本, 只要你的脚本遵守下一节所陈列的规则即可,只要那个语言能在你的Web服务器系统上运行.

在这本学习手册中,仅用两种语言编写CGI脚本: UNIX shell和 Perl语言. 这个shell是适合在任何相近的UNIX系统上运行并且容易学习, 但是处理复杂的情况就困难了. Perl, 就要用这个语言了, 它是免费的, 这个语言是稳定和强大的,类似C,但它也是较难学习的. 你的服务器设置正确了吗?

为了运行任何一个CGI脚本, 不管简单或复杂的,你的服务器必须设置成能够运行他们,必须放置在一个特定的目录,必须有一个依赖你服务器设定的文件扩展名. 如果你是租用服务器,就要是否允许运行CGI脚本.

如果你拥有自己的服务器,检查你的服务器说明书是怎样处理CGI脚本的. 如果你用的不是UNIX? 只好再找别的学习手册了。 解剖一个CGI脚本

如果你编写它很久,克服很多警告和配置,恭喜你,你已经会些CGI脚本,并且可以在你的网页上使用了. 在这一章,将学习脚本是怎样执行,你的服务器又是怎样与他们对话产生回应的。 输出头部

虽然你的CGI脚本可以让你做任何事情,但是脚本的输出还是必须有一个规定形式.

这个 \脚本输出\意思是指你的脚本发回服务器的数据. 在UNIX系统中, 输出是发向标准输出, 服务器从那儿检测它. 在其他系统和服务器, 你的脚本输出也许不一样了.

这个头部是实际不是文本的一部分,是服务器与浏览器之间的信息协议,你实际看不到。 有三个类型的头部: Content-type, Location, 和Status. Content-type 最普遍的。

有关content-type解释可以见有关HTML的说明, 一个你可以发出的特定编码象这样: Content-type: text/html

在这个例子中,输出数据的类型是text/html; 换句话说, 他是个HTML文件. 表1. 通用格式和content-types. Format HTML Text GIF JPEG PostScript MPEG Content-Type text/html text/plain image/gif image/jpeg application/postscript video/mpeg 注意content-type 后面必须跟一个空行. 如果你没有空行,服务器将无法搞清这个头部在哪里结束。

输出数据

你输出的数据应该符合你所规定的content-type; 如果content-type是text/html, 输出安置应该是在HTML. 如果content-type是image/gif, 输出应该是在一个二进制的GIF文件. T这是个简单的输出日期的简单脚本,这个CGI脚本还检查看看我是否已经登陆到我的Web服务器,并且报告发现了什么(如在图4). 图4. 脚本的结果

这是个很简单的例子, 他能这样备调用:

echo Content-type: text/html

echo \

echo \

echo \

为了测试我是否已经登陆系统,用who命令(我的登陆名假设为lemay), 储存结果在变量ison中. 如果我登陆, 变量ison将有些内容,否则则是空的. ison='who | grep lemay'

试验结果及返回相应提示的脚本是这样: if [ ! -z \

echo \ else

echo \ fi

最后关闭HTML:

echo \

现在你通过从命令行运行他,测试一下,你将得到一个结果说我未登陆你的系统,当然不可能的,他的输出是这样的: Content-type: text/html

Are You There?

Laura is not logged in.

这是输出的一个HTML文本,这样你的浏览器能正常显示他,因为他是个HTML文件。

现在将他copy到你的服务器的cgi-bin目录下,去执行,如果你不能达到CGI-bin目录,你必须询问你的服务器管理者,你不能理所当然地自己建立个CGI-bin目录,那没用的。 这个例子完整的脚本如下: #!/bin/sh

echo \ echo

echo \

echo \

echo \

ison='who | grep lemay'

if [ ! -z \

echo \ else

echo \ fi

echo \带有参数的脚本

为了传递一个参数给脚本,可以在URL中使用 (?) 插入脚本名词和参数之间, 用加号(+) 表示每个单一的参数, 如:

这个方法有时叫查询, 因为早期它用在搜索功能中. 既然你知道怎样使用参数,让我们继续上面的例子pinglaura,通过修改这个例子我们得到下面这个脚本pinggeneric. 我们取个不同题目: #!/bin/sh

echo \ echo

echo \

echo \

echo \

在上面的例子中, 下一步应该是测试我是否登陆,在这里我们用参数${1}代替我的名字lemay, ${1}作为第一个参数, ${2}作为第二个, ${3}作为第三个. ison='who | grep \剩下的所有修改如下: if [ ! -z \

echo \ else

echo \ fi

echo \

好了,让我们修改HTML页中的连接吧!原来是这样:

有第二种方法传递信息给CGI脚本. 它叫作路径信息path information 用作那些在脚本调用是不用变更的参数, 象一个临时文件名或调用脚本自己的文件名. 正如你看到的,在上面的例子问号后面的参数是因用户表单的输入而改变的. 路径信息Path info用作其他信息传递给脚本,实际上,你可以用它作任何事情.

路径信息Path information是一种不象通常参数脚本那样频繁传递信息的方法. 路径Path information通常是指Web服务器上的那些比如配置文件、临时文件或者被脚本因问题调用的文件等等此类文件.

看下面一个路径信息path information例子, :

http://myhost/cgi-bin/myscript/remaining_path_info?arg1+arg2

当脚本运行时,在路径中的信息将被放置于环境参数PATH_INFO. 你能在你的脚本内容中使用这些信息.

比如说, 让我们假设你在多页上已有多个连接到同一个脚本. 你能用这个路径信息显示那个有连接的HTML文件名. 这样, 在你完成处理你的脚本之后, 当你发回一个HTML文件时, 你能在这个文件里包含一个连接,发回用户一开始那个页。

你会在下一章节学到更多路径信息:有用的表单和脚本. 待后来登出 创建一个特殊的脚本输出

现在你已经学习了诸如输出数据 一般地HTML数据 发给浏览器解释显示的数据. 但是如果你不想把脚本结果作为一个数据流形式发回浏览器,而是想把一个存在的页发回,怎么办? 如果你只是要脚本做一些事而不让任何结果回答给浏览器,怎么办? 不用怕, 这里开始解释这些情况. 用调用另一个文本作为响应 CGI输出不是非得一个数据流,有时可以告诉浏览器是存在服务器上的一个页,为了发出这个信息,看下面的例子: Location: ../docs/final.html

这个Location行用作通常的输出位置,也就是说,如果你用了Location, 你就不必再用象Content-type这样的数据输出(实际上,你也不能). 正如Content-type, 你也必须在这一行后面跟一个空行.

指向这个文件的路径可以是一个URL或相对路径. 所有相对路径是指相对于脚本所在的位置. 例子中的final.html文本是在当前上一个目录下docs的目录下: echo Location: ../docs/final.html echo

你不能Content-type 和 Location两个输出同时使用. 比如, 如果你想输出一个标准页,但是想在这个页尾加上客户的内容, 你就得用Content-type自行组建这两个部分. 注意:你可以用脚本命令打开一个当地文件作为数据直接将之输出. No Response

有时对于一个CGI脚本也许一点没有输出. 有时你只是要从用户那儿收集点信息. 你就不用再调用一个新文本, 也不用输出结果或打开一个存在的文件. 在浏览器上的屏幕还是那个样子.

很幸运, 这一切很容易. 你只要输出下面这个命令即可(后面跟一个空行): echo Status: 204 No Response echo

这个Status头部提供状态码给服务器(并且也给浏览器). 特别的204将传递给浏览器,如果能识别它,它将什么也不做.

尽管无响应是一个官方HTTP规定的一部分,但也并不是适合所有的浏览器,也许会产生奇怪的结果,那你要多试验试试看啦. 处理表单的脚本 今天,大多数CGI脚本是用来处理表单输入的. 这个过程大致象上面说阐述的一样,但还是有些不同,比如CGI脚本只要被调用;数据怎样从服务器被发向浏览器.

记住, 大多数表单有两个部分: HTML的表单格式;处理表单数据的CGI脚本. 这个CGI脚本使用标签

属性调用的.

表单形式和表单脚本

正如上面所说,由于表单有两个部分. 如下: 这个ACTION属性包含着处理表单的脚本:

如果你在用uncgi从input中解码, 情况有点不同. 为了是uncgi正常工作, 你首先必须调用uncgi , 如果uncgi是个目录,加上实际的脚本名, 象这样:

这样,你不必修改表单中原始的HTML; 原始的HTML可以工作得很好. 脚本

处理表单输入的是个CGI脚本, 让我们来仔细地看看。

在脚本中第一步是解码,在这个例子中, 我们已经使用uncgi解码输入数据, 实际这个表单已经为你做好解码. 通过建立一个uncgi的目录,一旦表单递交给服务器,服务器会自动进行解码,这样,所有的name/value已经准备就绪等待你的使用. 现在,一个例子开始部分假设是下面这样: echo Content-type: text/html echo

echo \

echo \

echo \

echo \

接下来,有两种情况要处理:一件是处理用户不输入名字的情况,一个是如果输入了向他们说hello.

这个Name元素的值, 是包含在WWW_theName环境变量中. 用一个简单的测试命令(-z), 你能查看环境变量是否是空的还是包括相应的输出值: if [ ! -z \

echo \

echo $WWW_theName

else

echo \ fi

最后增加一个连接\用来返回:

echo \

echo \ 问题

这里是使用CGI脚本比较普遍的问题: 脚本内容只显示不执行.

你正确配置了你的服务器运行CGI脚本? 你的脚本是放置在cgi-bin目录中吗?如果你的服务器允许带.cgi扩展名的CGI运行, 你的脚本文件名的扩展名是这样吗? Error 500: Server doesn't support POST.

解答还是如上一条一样,然后你用命令行执行你的CGI,可以正常运行吗?是否有错误?. Document contains no data.

确定你的头部行和数据部之间有一空行. Error 500: Bad Script Request.

确定你的脚本是可执行的(在UNIX, 用chmod +x 你的脚本.cgi). 在从浏览器运行之前,你应当从命令行运行你的脚本,如果客户端是win95,可以用telnet登陆你的服务器,执行命令行,当然必须了解UNIX命令. CGI变量

表2 总结那些环境变量. 表2. CGI 环境变量. 环境变量 SERVER_NAME SERVER_SOFTWARE GATEWAY_INTERFACE SERVER_PROTOCOL SERVER_PORT REQUEST_METHOD 意义 CGI脚本运行时的主机名和IP地址. 你的服务器的类型如: CERN/3.0 或 NCSA/1.3. 运行的CGI版本. 对于UNIX服务器, 这是CGI/1.1. 服务器运行的HTTP协议. 这里当是HTTP/1.0. 服务器运行的TCP口,通常Web服务器是80. POST 或 GET, 取决于你的表单是怎样递交的. HTTP_ACCEPT HTTP_USER_AGENT HTTP_REFERER PATH_INFO PATH_TRANSLATED SCRIPT_NAME 浏览器能直接接收的Content-types, 可以有HTTP Accept header定义. 递交表单的浏览器的名称、版本 和其他平台性的附加信息。 递交表单的文本的 URL,不是所有的浏览器都发出这个信息,不要依赖它 附加的路径信息, 由浏览器通过GET方法发出. 在PATH_INFO中系统规定的路径信息. 指向这个CGI脚本的路径, 是在URL中显示的(如, /cgi-bin/thescript). 脚本参数或者表单输入项(如果是用GET递交). QUERY_STRING 包含URL中问号后面的参数. 递交脚本的主机名,这个值不能被设置. 递交脚本的主机IP地址. 递交脚本的用户名. 如果服务器的authentication被激活,这个值可以设置。 如果Web服务器是在ident (一种确认用户连接你的协议)运行, 递交表单的系统也在运行ident, 这个变量就含有ident返回值. 如果表单是用POST递交, 这个值将是 application/x-www-form-urlencoded. 在上载文件的表单中, content-type 是个 multipart/form-data. 对于用POST递交的表单, 标准输入口的字节数. QUERY_STRING REMOTE_HOST REMOTE_ADDR REMOTE_USER REMOTE_IDENT CONTENT_TYPE CONTENT_LENGTH 表单输入的解码程序

目前有两个程序: 通用目的的uncgi, 和cgi-lib.pl, 这是个Perl库,用于perl编写的CGI脚本. 当然也有表单上载时可以解码的程序,很少。 uncgi

说明原码可以从 http://www.hyperion.com/~koreth/uncgi.html获得。 cgi-lib.pl

这是由Steve Brenner编写的, 帮助你管理输入. 他能从GET和POST获取输入并且放置在一个Perl列表或阵列中. 更新的版本也能处理来自表单的文件上传. 从这儿可以得到信息与原码 http://www.bio.cam.ac.uk/cgi-lib. 如果你决定用Perl语言处理你的表单输入,cgi-lib是个很好的库.

为了使用cgi-lib.pl,你通常要这样写: #!/usr/lib/perl require 'cgi-lib.pl';

cgi-lib中尽管有很多子程序, 最重要的是ReadParse子程. ReadParse 读取输入方便地将name/value储存在一个Perl阵列中. 在你的Perl脚本中通常是这样调用的:

&ReadParse(*in);

此例中,阵列名是in, 可以随便取名的.

在表单输入解码后, 你能读取和处理这个name/value,方法是象下面这样: print $in{'theName'};

这个将显示名字name是theName的值value.

如果你有多个用同样名字的name对, cgi-lib.pl用(\\0)分隔多个名字. 这样可以正常处理你的脚本.

解码上传的文件输入

基于表单的文件上传需要不同的表单输入,有一些程序可以对其进行解码。

cgi-lib.pl 后来版本可以很好支持, 在http://www.bio.cam.ac.uk/cgi-lib/ 了解更多的情况. 另一个处理用Perl编写的CGI地址是 http://valine.ncsa.uiuc.edu/cgi_docs.html . 自己做

找专门书籍学习吧: ftp://ds.internic.net/rfc/rfc1867.txt. 非解剖的脚本头部

按照本书阐述,大多数情况可以正常操作,在一些情况下不是这样的,你可以翻阅说明书了解。

脚本

为了在CGI中完成讨论组, 我们看看叫的搜索. 这是早期在浏览器中用来向服务器发出搜索关键字的办法,参看以前的资料。 总结

CGI脚本, 有时叫服务器端脚本或网关脚本。 在internet上有很多免费资源,你可以搜索下载读懂他们,当然都是英文的,如果你下决心翻译他们(可能更加强理解). 这样一举两得啊.

注意:上述程序可以用ultra edit来编辑,注意转换UNIX格式 ,必须采用UNIX格式存盘,再上载,用telnet登陆,在命令行键入perl sample.pl,看有无bug,再 在浏览器中调用。CGI程序包括放置CGI的目录一定要改属性为777, 要写入的HTML文件也要改属性为777. 现在网上有很多免费的cgi,基本可以满足一般需求,请到这个网址查询你要的cgi:http://www.itm.com/cgicollection/

perl简单变量 整型 浮点数 字符串

作者: 字体:[增加 减小] 类型:转载

基本上,简单变量就是一个数据单元,这个单元可以是数字或字符串。 一、整型 1、整型

PERL最常用的简单变量,由于其与其它语言基本相同,不再赘述。 例:

$x = 12345;

if (1217 + 116 == 1333) { # statement block goes here }

整型的限制:

PERL实际上把整数存在你的计算机中的浮点寄存器中,所以实际上被当作浮点数看待。在多数计算机中,浮点寄存器可以存贮约16位数字,长于此的被丢弃。整数实为浮点数的特例。

2、8进制和16进制数

8进制以0打头,16进制以0x打头。 例:$var1 = 047; (等于十进制的39) $var2 = 0x1f; (等于十进制的31) 二、浮点数

如 11.4 、 -0.3 、.3 、 3. 、 54.1e+02 、 5.41e03

浮点寄存器通常不能精确地存贮浮点数,从而产生误差,在运算和比较中要特别注意。指数的范围通常为-309到+308。 例:

#!/usr/local/bin/perl

$value = 9.01e+21 + 0.01 - 9.01e+21; print (\ $value = 9.01e+21 - 9.01e+21 + 0.01; print (\

---------------------------------------------------------

$ program3_3 first value is 0

second value is 0.01 三、字符串

惯用C的程序员要注意,在PERL中,字符串的末尾并不含有隐含的NULL字符,NULL字符可以出现在串的任何位置。

. 双引号内的字符串中支持简单变量替换,例如: $number = 11;

$text = \

则$text的内容为:\

.双引号内的字符串中支持转义字符 Table 3.1. Escape sequences in strings. Escape Sequence \\a \\b \\cn \\e Description Bell (beep) Backspace The Ctrl+n character Escape \\E \\f \\l \\L \\n \\r \\Q Ends the effect of \\L, \\U or \\Q Form feed Forces the next letter into lowercase All following letters are lowercase Newline Carriage return Do not look for special pattern characters \\t \%u \\U \\v Tab Force next letter into uppercase All following letters are uppercase Vertical tab \\L、\\U、\\Q功能可以由\\E关闭掉,如: $a = \

.要在字符串中包含双引号或反斜线,则在其前加一个反斜线,反斜线还可以取消变量替换,如:

$res = \ $result = 14;

print (\的结果为: The value of $result is 14.

.可用\\nnn(8进制)或\\xnn(16进制)来表示ASCII字符,如: $result = \ $result = \

.单引号字符串

单引号字符串与双引号字符串有两个区别,一是没有变量替换功能,二是反斜线不支持转义字符,而只在包含单引号和反斜线时起作用。单引号另一个特性是可以跨多行,如: $text = 'This is two lines of text ';

与下句等效:

$text = \

.字符串和数值的互相转换 例1:

$string = \ $number = 28;

$result = $string + $number; # $result = 71

若字符串中含有非数字的字符,则从左起至第一个非数字的字符,如: $result = \ $result = \

.变量初始值

在PERL中,所有的简单变量都有缺省初始值:\,即空字符。但是建议给所有变量赋初值,否则当程序变得大而复杂后,很容易出现不可预料且很难调试的错误。

perl操作符详细说明

作者: 字体:[增加 减小] 类型:转载

一、算术操作符 :+(加)、-(减)、*(乘)、/(除)、**(乘幂)、%(取余)、-(单目负) (1)乘幂的基数不能为负,如 (-5) ** 2.5 # error;

(2)乘幂结果不能超出计算机表示的限制,如10 ** 999999 # error

(3)取余的操作数如不是整数,四舍五入成整数后运算;运算符右侧不能为零 (4)单目负可用于变量: - $y ; # 等效于 $y * -1 二、整数比较操作符

Table 3.1. 整数比较操作符 操作符 < > == <= >= != <=> 描述 小于 大于 等于 小于等于 大于等于 不等于 比较,返回 1, 0, or -1 操作符<=>结果为: 0 - 两个值相等 1 - 第一个值大 1 - 第二个值大 三、字符串比较操作符 Table 3.2. 字符串比较操作符 操作符 lt gt eq le ge ne cmp 描述 小于 大于 等于 小于等于 大于等于 不等于 比较,返回 1, 0, or -1 四、逻辑操作符 逻辑或:$a || $b 或 $a or $b

逻辑与:$a && $b 或 $a and $b 逻辑非:! $a 或 not $a 逻辑异或:$a xor $b 五、位操作符 位与:& 位或:| 位非:~ 位异或:^ 左移:$x << 1 右移:$x >> 2

注:不要将&用于负整数,因为PERL将会把它们转化为无符号数。 六、赋值操作符 Table 3.3. 赋值操作符 操作符 = += -= 描述 Assignment only Addition and assignment Subtraction and assignment *= /= %= **= &= |= ^= Multiplication and assignment Division and assignment Remainder and assignment Exponentiation and assignment Bitwise AND and assignment Bitwise OR and assignment Bitwise XOR and assignment Table 3.4. 赋值操作符例子 表达式 $a = 1; $a -= 1; $a *= 2; $a /= 2; $a %= 2; $a **= 2; $a &= 2; $a |= 2; $a ^= 2; 等效表达式 none (basic assignment) $a = $a - 1; $a = $a * 2; $a = $a / 2; $a = $a % 2; $a = $a ** 2; $a = $a & 2; $a = $a | 2; $a = $a ^ 2; .=可在一个赋值语句中出现多次,如: $value1 = $value2 = \.=作为子表达式 ($a = $b) += 3; 等价于 $a = $b; $a += 3;

但建议不要使用这种方式。

七、自增自减操作符 :++、--(与C++中的用法相同) .不要在变量两边都使用此种操作符:++$var-- # error

.不要在变量自增/减后在同一表达式中再次使用:$var2 = $var1 + ++$var1; # error .在PERL中++可用于字符串,但当结尾字符为'z'、'Z'、'9'时进位,如: $stringvar = \

$stringvar++; # $stringvar contains \

$stringvar = \

$stringvar++; # $stringvar contains \

$stringvar = \

$stringvar++; # $stringvar now contains \

$stringvar = \

$stringvar++; # $stringvar now contains \

$stringvar = \

$stringvar++; # $stringvar now contains \

$stringvar = \

$stringvar++; # $stringvar now contains \

.不要使用--,PERL将先将字符串转换为数字再进行自减 $stringvar = \

$stringvar--; # $stringvar = -1 now

.如果字符串中含有非字母且非数字的字符,或数字位于字母中,则经过++运算前值转换为数字零,因此结果为1,如: $stringvar = \ $stringvar++;

$stringvar = \ $stringvar++;

八、字符串联结和重复操作符 联接: . 重复:x

联接且赋值(类似+=): .= 例:

$newstring = \ $newstring = \ $a = \

$a .= \九、逗号操作符

其前面的表达式先进行运算,如: $var1 += 1, $var2 = $var1;

等价于 $var1 += 1; $var2 = $var1;

使用此操作符的唯一理由是提高程序的可读性,将关系密切的两个表达式结合在一起,如: $val = 26;

$result = (++$val, $val + 5); # $result = 32 注意如果此处没有括号则意义不同: $val = 26;

$result = ++$val, $val + 5; # $result = 27 十、条件操作符

与C中类似,条件?值1:值2,当条件为真时取值1,为假时取值2,如: $result = $var == 0 ? 14 : 7;

$result = 43 + ($divisor == 0 ? 0 : $dividend / $divisor);

PERL 5中,还可以在赋值式左边使用条件操作符来选择被赋值的变量,如: $condvar == 43 ? $var1 : $var2 = 14;

$condvar == 43 ? $var1 = 14 : $var2 = 14; 十一、操作符的次序 Table 3.6. 操作符次序 操作符 ++, -- -, ~, ! ** =~, !~ *, /, %, x +, -, . <<, >> -e, -r, etc. <, <=, >, >=, lt, le, gt, ge ==, !=, <=>, eq, ne, cmp & 描述 自增,自减 单目 乘方 模式匹配 乘,除,取余,重复 加,减,联接 移位 文件状态 不等比较 相等比较 位与 |, ^ && || .. ? and : =, +=, -=, *=, and so on , not 位或,位异或 逻辑与 逻辑或 列表范围 条件操作符 赋值 逗号操作符 Low-precedence logical NOT and Low-precedence logical AND or, xor Low-precedence logical OR and XOR .操作符结合性(associativity): Table 3.7. 操作符结合性 操作符 ++, -- -, ~, ! ** =~, !~ *, /, %, x +, -, . <<, >> 结合性 无 Right-to-left Right-to-left Left-to-right Left-to-right Left-to-right Left-to-right -e, -r, <, <=, >, >=, lt, le, gt, ge ==, !=, <=>, eq, ne, cmp & |, ^ && || .. ? and : =, +=, -=, *=, and so on , not and or, xor 无 Left-to-right Left-to-right Left-to-right Left-to-right Left-to-right Left-to-right Left-to-right Right-to-left Right-to-left Left-to-right Left-to-right Left-to-right Left-to-right 建议: 1、当你不确定某操作符是否先执行时,一定要用括号明确之。 2、用多行、空格等方式提高程序的可读性。

perl 列表和数组变量详解

作者: 字体:[增加 减小] 类型:转载

一、列表

列表是包含在括号里的一序列的值,可以为任何数值,也可为空,如:(1, 5.3 , \,空列表:()。

注:只含有一个数值的列表(如:(43.2) )与该数值本身(即:43.2 )是不同的,但它们可以互相转化或赋值。 列表例:

(17, $var, \ (17, 26 << 2)

(17, $var1 + $var2)

($value, \ 二、数组--列表的存贮

列表存贮于数组变量中,与简单变量不同,数组变量以字符\打头,如: @array = (1, 2, 3); 注:

(1)数组变量创建时初始值为空列表:()。

(2)因为PERL用@和$来区分数组变量和简单变量,所以同一个名字可以同时用于数组变量和简单变量,如: $var = 1;

@var = (11, 27.1 , \ 但这样很容易混淆,故不推荐。 1、数组的存取

.对数组中的值通过下标存取,第一个元素下标为0。试图访问不存在的数组元素,则结果为NULL,但如果给超出数组大小的元素赋值,则数组自动增长,原来没有的元素值为NULL。如:

@array = (1, 2, 3, 4); $scalar = $array[0];

$array[3] = 5; # now @array is (1,2,3,5) $scalar = $array[4]; # now $scalar = null;

$array[6] = 17; # now @array is (1,2,3,5,\ .数组间拷贝

@result = @original; .用数组给列表赋值 @list1 = (2, 3, 4);

@list2 = (1, @list1, 5); # @list2 = (1, 2, 3, 4, 5) .数组对简单变量的赋值 (1) @array = (5, 7, 11);

($var1, $var2) = @array; # $var1 = 5, $var2 = 7, 11被忽略 (2) @array = (5, 7);

($var1, $var2, $var3) = @array; # $var1 = 5, $var2 = 7, $var3 =\ .从标准输入(STDIN)给变量赋值 $var = ;

@array = ; # ^D为结束输入的符号 2 、字符串中的方括号和变量替换

\为数组@var的第一个元素。

\将字符\转义,等价于\,$var被变量替换,[0]保持不变。 \亦等价于\。

\则取消了大括号的变量替换功能,包含文字:${var}. 3、列表范围:

(1..10) = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10) (2, 5..7, 11) = (2, 5, 6, 7, 11) (3..3) = (3) .用于实数

(2.1..5.3) = (2.1, 3.1 ,4.1, 5.1) (4.5..1.6) = () .用于字符串

(\ @day_of_month = (\ .可包含变量或表达式 ($var1..$var2+5) .小技巧:

$fred = \

print ((\ 其结果为: Hello, Fred! Hello, Fred! 4、数组的输出: (1) @array = (1, 2, 3); print (@array, \ 结果为: 123

(2) @array = (1, 2, 3); print (\ 结果为: 1 2 3

5、列表/数组的长度

当数组变量出现在预期简单变量出现的地方,则PERL解释器取其长度。 @array = (1, 2, 3);

$scalar = @array; # $scalar = 3,即@array的长度

($scalar) = @array; # $scalar = 1,即@array第一个元素的值 注:以数组的长度为循环次数可如下编程: $count = 1;

while ($count <= @array) {

print (\ $count++; }

6、子数组

@array = (1, 2, 3, 4, 5);

@subarray = @array[0,1]; # @subarray = (1, 2) @subarray2 = @array[1..3]; # @subarray2 = (2,3,4)

@array[0,1] = (\ @array[0..3] = (11, 22, 33, 44); # @array = (11,22,33,44,5) now @array[1,2,3] = @array[3,2,4]; # @array = (11,44,33,5,5) now @array[0..2] = @array[3,4]; # @array = (5,5,\ 可以用子数组形式来交换元素: @array[1,2] = @array[2,1]; 7、有关数组的库函数

(1)sort--按字符顺序排序

@array = (\

@array2 = sort(@array); # @array2 = (\ @array = (70, 100, 8);

@array = sort(@array); # @array = (100, 70, 8) now ( 2)reverse--反转数组

@array2 = reverse(@array); @array2 = reverse sort (@array); (3)chop--数组去尾

chop的意义是去掉STDIN(键盘)输入字符串时最后一个字符--换行符。而如果它作用到数组上,则将数组中每一个元素都做如此处理。 @list = (\

chop (@list); # @list = (\ ( 4)join/split--连接/拆分

join的第一个参数是连接所用的中间字符,其余则为待连接的字符数组。 $string = join(\结果为\ @list = (\

$string = join(\结果为\ @array = split(/::/,$string); # @array = (\

perl 文件读写详细说明

作者: 字体:[增加 减小] 类型:转载

一、打开、关闭文件

语法为open (filevar, filename),其中filevar为文件句柄,或者说是程序中用来代表某文件的代号,filename为文件名,其路径可为相对路径,亦可为绝对路径。 open(FILE1,\

open(FILE1, \

打开文件时必须决定访问模式,在PERL中有三种访问模式:读、写和添加。后两种模式的区别在于写模式将原文件覆盖,原有内容丢失,形式为:open(outfile,\而添加模式则在原文件的末尾处继续添加内容,形式为:open(appendfile, \。要注意的是,不能对文件同时进行读和写/添加操作。

open的返回值用来确定打开文件的操作是否成功,当其成功时返回非零值,失败时返回零,因此可以如下判断:

if (open(MYFILE, \

# here's what to do if the file opened successfully }

当文件打开失败时结束程序: unless (open (MYFILE, \ die (\ }

亦可用逻辑或操作符表示如下:

open (MYFILE, \ 当文件操作完毕后,用close(MYFILE); 关闭文件。

二、读文件

语句$line = ;从文件中读取一行数据存储到简单变量$line中并把文件指针向后移动一行。为标准输入文件,通常为键盘输入,不需要打开。

语句@array = ;把文件的全部内容读入数组@array,文件的每一行(含回车符)为@array的一个元素。 三、写文件 形式为:

open(OUTFILE, \

print OUTFILE (\

注:STDOUT、STDERR为标准输出和标准错误文件,通常为屏幕,且不需要打开。 四、判断文件状态 1、文件测试操作符

语法为:-op expr,如: if (-e \

print STDERR (\ } 文件测试操作符 操作符 -b -c -d -e -f -g -k -l -o -p -r -s 描述 是否为块设备 是否为字符设备 是否为目录 是否存在 是否为普通文件 是否设置了setgid位 是否设置了sticky位 是否为符号链接 是否拥有该文件 是否为管道 是否可读 是否非空 -t -u -w -x -z -A -B -C -M -O -R -S -T -W -X 是否表示终端 是否设置了setuid位 是否可写 是否可执行 是否为空文件 距上次访问多长时间 是否为二进制文件 距上次访问文件的inode多长时间 距上次修改多长时间 是否只为“真正的用户”所拥有 是否只有“真正的用户”可读 是否为socket 是否为文本文件 是否只有\真正的用户\可写 是否只有\真正的用户\可执行 注:“真正的用户”指登录时指定的userid,与当前进程用户ID相对,命令suid可以改变有效用户ID。 例: unless (open(INFILE, \

die (\ }

if (-e \

die (\ }

unless (open(OUTFILE, \

die (\ } 等价于

open(INFILE, \

open(OUTFILE, \五、命令行参数

象C一样,PERL也有存储命令行参数的数组@ARGV,可以用来分别处理各个命令行参数;与C不同的是,$ARGV[0]是第一个参数,而不是程序名本身。 $var = $ARGV[0]; # 第一个参数 $numargs = @ARGV; # 参数的个数

PERL中,<>操作符实际上是对数组@ARGV的隐含的引用,其工作原理为: 1、当PERL解释器第一次看到<>时,打开以$ARGV[0]为文件名的文件;

2、执行动作shift(@ARGV); 即把数组@ARGV的元素向前移动一个,其元素数量即减少了一个。

3、<>操作符读取在第一步打开的文件中的所有行。 4、读完后,解释器回到第一步重复。 例:

@ARGV = (\实际上由命令行参数赋值 while ($line = <>) { print ($line); }

将把文件myfile1和myfile2的内容打印出来。 六、打开管道

用程序的形式也可以象命令行一样打开和使用管道(ex:ls > tempfile)。如语句open (MYPIPE, \cat >hello\打开一个管道,发送到MYPIPE的输出成为命令\>hello\的输入。由于cat命令将显示输入文件的内容,故该语句等价于open(MYPIPE, \用管道发送邮件如下:

open (MESSAGE, \

print MESSAGE (\ close (MESSAGE);

perl 模式匹配参数详解

作者: 字体:[增加 减小] 类型:转载

一、简介

模式指在字符串中寻找的特定序列的字符,由反斜线包含:/def/即模式def。其用法如结合函数split将字符串用某模式分成多个单词:@array = split(/ /, $line); 二、匹配操作符 =~、!~ =~检验匹配是否成功:$result = $var =~ /abc/;若在该字符串中找到了该模式,则返回非零值,即true,不匹配则返回0,即false。!~则相反。 这两个操作符适于条件控制中,如: if ($question =~ /please/) {

print (\ } else {

print (\ }

三、模式中的特殊字符

PERL在模式中支持一些特殊字符,可以起到一些特殊的作用。 1、字符 +

+意味着一个或多个相同的字符,如:/de+f/指def、deef、deeeeef等。它尽量匹配尽可能多的相同字符,如/ab+/在字符串abbc中匹配的将是abb,而不是ab。 当一行中各单词间的空格多于一个时,可以如下分割: @array = split (/ +/, $line);

注:split函数每次遇到分割模式,总是开始一个新单词,因此若$line以空格打头,则@array的第一个元素即为空元素。但其可以区分是否真有单词,如若$line中只有空格,则@array则为空数组。且上例中TAB字符被当作一个单词。注意修正。 2、字符 []和[^]

[]意味着匹配一组字符中的一个,如/a[0123456789]c/将匹配a加数字加c的字符串。与+联合使用例:/d[eE]+f/匹配def、dEf、deef、dEdf、dEEEeeeEef等。^表示除其之外的所有字符,如:/d[^deE]f/匹配d加非e字符加f的字符串。 3、字符 *和?

它们与+类似,区别在于*匹配0个、1个或多个相同字符,?匹配0个或1个该字符。如/de*f/匹配df、def、deeeef等;/de?f/匹配df或def。 4、转义字符

如果你想在模式中包含通常被看作特殊意义的字符,须在其前加斜线\。如:/\\*+/中\\*即表示字符*,而不是上面提到的一个或多个字符的含义。斜线的表示为/\\\\/。在PERL5中可用字符对\\Q和\\E来转义。 5、匹配任意字母或数字

上面提到模式/a[0123456789]c/匹配字母a加任意数字加c的字符串,另一种表示方法为:/a[0-9]c/,类似的,[a-z]表示任意小写字母,[A-Z]表示任意大写字母。任意大小写字母、数字的表示方法为:/[0-9a-zA-Z]/。 6、锚模式 锚 ^ 或 \\A $ 或 \\Z \\b \\B 描述 仅匹配串首 仅匹配串尾 匹配单词边界 单词内部匹配 例1:/^def/只匹配以def打头的字符串,/$def/只匹配以def结尾的字符串,结合起来的/^def$/只匹配字符串def(?)。\\A和\\Z在多行匹配时与^和$不同。 例2:检验变量名的类型:

if ($varname =~ /^\\$[A-Za-z][_0-9a-zA-Z]*$/) { print (\

} elsif ($varname =~ /^@[A-Za-z][_0-9a-zA-Z]*$/) { print (\ } elsif ($varname =~ /^[A-Za-z][_0-9a-zA-Z]*$/) { print (\

} else {

print (\ } 例3:\\b在单词边界匹配:/\\bdef/匹配def和defghi等以def打头的单词,但不匹配abcdef。/def\\b/匹配def和abcdef等以def结尾的单词,但不匹配defghi,/\\bdef\\b/只匹配字符串def。注意:/\\bdef/可匹配$defghi,因为$并不被看作是单词的部分。

例4:\\B在单词内部匹配:/\\Bdef/匹配abcdef等,但不匹配def;/def\\B/匹配defghi等;/\\Bdef\\B/匹配cdefg、abcdefghi等,但不匹配def,defghi,abcdef。 7、模式中的变量替换 将句子分成单词: $pattern = \

@words = split(/$pattern/, $line); 8、字符范围转义

E 转义字符 \\d \\D \\w \\W \\s \\S

描述 任意数字

除数字外的任意字符 任意单词字符 任意非单词字符 空白 非空白

范围 [0-9] [^0-9] [_0-9a-zA-Z] [^_0-9a-zA-Z]

[ \\r\\t\\n\\f] [^ \\r\\t\\n\\f]

例:/[\\da-z]/匹配任意数字或小写字母。 9、匹配任意字符

字符\匹配除换行外的所有字符,通常与*合用。 10、匹配指定数目的字符

字符对{}指定所匹配字符的出现次数。如:/de{1,3}f/匹配def,deef和deeef;/de{3}f/匹配deeef;/de{3,}f/匹配不少于3个e在d和f之间;/de{0,3}f/匹配不多于3个e在d和f之间。 11、指定选项

字符\指定两个或多个选择来匹配模式。如:/def|ghi/匹配def或ghi。 例:检验数字表示合法性

if ($number =~ /^-?\\d+$|^-?0[xX][\\da-fa-F]+$/) { print (\ } else {

print (\ }

其中 ^-?\\d+$ 匹配十进制数字,^-?0[xX][\\da-fa-F]+$ 匹配十六进制数字。 12、模式的部分重用

当模式中匹配相同的部分出现多次时,可用括号括起来,用\\n来多次引用,以简化表达

式:

/\\d{2}([\\W])\\d{2}\\1\\d{2}/ 匹配: 12-05-92 26.11.87 07 04 92等

注意:/\\d{2}([\\W])\\d{2}\\1\\d{2}/ 不同于/(\\d{2})([\\W])\\1\\2\\1/ ,后者只匹配形如17-17-17的字符串,而不匹配17-05-91等。 13、转义和特定字符的执行次序 象操作符一样,转义和特定字符也有执行次序: 特殊字符 () + * ? {} ^ $ \\b \\B | 描述 模式内存 出现次数 锚 选项 14、指定模式定界符

缺省的,模式定界符为反斜线/,但其可用字母m自行指定,如: m!/u/jqpublic/perl/prog1! 等价于/\\/u\\/jqpublic\\/perl\\/prog1/

注:当用字母'作为定界符时,不做变量替换;当用特殊字符作为定界符时,其转义功能或特殊功能即不能使用。 15、模式次序变量

在模式匹配后调用重用部分的结果可用变量$n,全部的结果用变量$&。 $string = \ $string =~ /-?(\\d+)\\.?(\\d+)/; # 匹配结果为25.11 $integerpart = $1; # now $integerpart = 25 $decimalpart = $2; # now $decimalpart = 11 $totalpart = $&; # now totalpart = 25.11 四、模式匹配选项 选项 g i m o s 描述 匹配所有可能的模式 忽略大小写 将串视为多行 只赋值一次 将串视为单行 x 忽略模式中的空白 1、匹配所有可能的模式(g选项)

@matches = \ 匹配的循环:

while (\ $match = $&;

print (\ }

结果为: ba la ta

当使用了选项g时,可用函数pos来控制下次匹配的偏移: $offset = pos($string); pos($string) = $newoffset; 2、忽略大小写(i选项)例

/de/i 匹配de,dE,De和DE。 3、将字符串看作多行(m选项)

在此情况下,^符号匹配字符串的起始或新的一行的起始;$符号匹配任意行的末尾。 4、只执行一次变量替换例 $var = 1;

$line = ; while ($var < 10) {

$result = $line =~ /$var/o; $line = ; $var++; }

每次均匹配/1/。

5、将字符串看作单行例

/a.*bc/s匹配字符串axxxxx \\nxxxxbc,但/a.*bc/则不匹配该字符串。 6、在模式中忽略空格

/\\d{2} ([\\W]) \\d{2} \\1 \\d{2}/x等价于/\\d{2}([\\W])\\d{2}\\1\\d{2}/。 五、替换操作符

语法为s/pattern/replacement/,其效果为将字符串中与pattern匹配的部分换成replacement。如:

$string = \

$string =~ s/123/456/; # now $string = \

在替换部分可使用模式次序变量$n,如s/(\\d+)/[$1]/,但在替换部分不支持模式的特殊字符,如{},*,+等,如s/abc/[def]/将把abc替换为[def]。 替换操作符的选项如下表: 选项 描述 g i e m o s x 改变模式中的所有匹配 忽略模式中的大小写 替换字符串作为表达式 将待匹配串视为多行 仅赋值一次 将待匹配串视为单行 忽略模式中的空白 1、匹配所有可能的模式(g选项) @matches = \ 匹配的循环:

while (\ $match = $&;

print (\ }

结果为: ba la ta

当使用了选项g时,可用函数pos来控制下次匹配的偏移: $offset = pos($string); pos($string) = $newoffset; 2、忽略大小写(i选项)例

/de/i 匹配de,dE,De和DE。 3、将字符串看作多行(m选项)

在此情况下,^符号匹配字符串的起始或新的一行的起始;$符号匹配任意行的末尾。 4、只执行一次变量替换例 $var = 1;

$line = ; while ($var < 10) {

$result = $line =~ /$var/o; $line = ; $var++; }

每次均匹配/1/。

5、将字符串看作单行例

/a.*bc/s匹配字符串axxxxx \\nxxxxbc,但/a.*bc/则不匹配该字符串。 6、在模式中忽略空格

本文来源:https://www.bwwdw.com/article/cyyr.html

Top