加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

Perl入门介绍

发布时间:2020-12-16 00:34:08 所属栏目:大数据 来源:网络整理
导读:Perl 是一种最初开发用于文本操作的编程语言。现在它能应用于广泛的任务,包括系统管理、 web 开发、 网络编程、 GUI 开发和更多的普通用途。 这个语言以实用性为目标(易用、高效、完整)宁愿失去美丽(小巧、优雅、迷你)。它使用方便,且支持面向过程和面

Perl 是一种最初开发用于文本操作的编程语言。现在它能应用于广泛的任务,包括系统管理、 web 开发、 网络编程、 GUI 开发和更多的普通用途。

这个语言以实用性为目标(易用、高效、完整)宁愿失去美丽(小巧、优雅、迷你)。它使用方便,且支持面向过程和面向对象编程,内置强大的文本处理支持,并有世界上最令人印象深刻的第三方模块的集中营。

运行Perl程序

在Unix命令行运行Perl程序:

perl progname.pl

另一种方法是,把这个放到你的脚本第一行:

?#!/usr/bin/env perl

然后用/path/to/script.pl运行。当然,首先得让它能执行,你得chmod 755 script.pl(Unix下)。

(这里的第一行假设你有env程序。你也可以直接把你的perl解释器的路径直接放到第一行,比如#!/usr/bin/perl)

安全保障

默认情况下,Perl非常随意。为了使它更强健建议每个程序由下列行开始:

??1.? #!/usr/bin/perl

??2. use strict;

??3. use warnings;

附加的两行从perl中捕获您的代码中的各种常见的问题。它们检查不同的事情,所以你需要两个都加上。一个潜在的问题通过use strict;捕获,一旦它捕获到问题,会马上让你的程序停止运行。当然使用use warnings;时,仅仅出现警告(就好像命令行的-w选项)并不会停止程序。

基本语法概述

一个Perl脚本或程序包含一条或多条语句。这些语句只需直接写在脚本中,而不需要像main()这样的东西作为程序入口。

Perl语句以分别结束:

print "Hello,world";

以星号(#)开始的语句是注释:

# This is a comment(这是一条注释)

空白字符会被Perl忽略:

??1.? print

??2. "Hello,world"

??3. ;

?

……引号里的字符串除外:

??1.? # this would print with alinebreak in the middle

??2. print "Hello

??3. world";

字符串使用双引号或单引号:

??1.? print "Hello,world";

??2. print 'Hello,world';

然而,只有双引号会“插入”变量值和像换行符(n)这样的特殊字符(转义字符):

??1.? print "Hello,$namen"; # works fine

??2. print 'Hello,$namen'; # prints $namen literally

数字不需要引号:

???print 42;

你可以使用或省略括号来传递函数的参数。它们只是在偶尔要改变或明确优先级的时候必须使用。

??1.? print("Hello,worldn");

??2. print "Hello,worldn";

Perl变量类型

Perl有3种主要的变量类型:标量(scalars)、数组(arrays)和哈希(hashes)。

???* 标量(Scalars)

?????一个标量表示只有一个值:

????????1.? my $animal ="camel";

????????2. my $answer = 42;

?????标量的值可以是字符串、整数或浮点数,并且Perl会在需要的时候自动转换。你不需要预先声明你的变量类型,但是你需要在第一次使用它们的时候,使用my来声明它们。(这是use strict;所要求的)

?????标量可以用不用的方式使用:

????????1.? print $animal;

????????2. print "The animal is $animaln";

????????3. print "The square of $answer is ",$answer * $answer,"n";

?

?????有大量的“魔法”标量的名称看上去像标点或线路噪音。这些特殊的变量用于各种目的。现在你只要知道其中一个,这就是“默认变量”$_。它被许多Perl的函数用作默认的参数,并且它被隐式设置到某些循环结构中。

?????????print;????????? # prints contentsof $_ by default(默认打印$_的内容)

???* 数组(Arrays)

?????数组用于表示一些值的列表:

????????1.? my @animals =("camel","llama","owl");

????????2. my @numbers = (23,42,69);

????????3. my @mixed = ("camel",1.23);

?????特殊变量$#array将返回数组最后一个元素的索引:

?????????print $mixed[$#mixed];?????? #last element,prints 1.23

?????你可能想使用$#array + 1来得到这个数组的元素个数。别急,这很容易。在Perl预想找到一个标量值的时候(“在标量上下文”),使用@array会得到数组的元素个数:(译注:“上下文”是Perl很重要的特性之一,请查阅相关文档或在无忧Perl搜索相关内容)

?????????if (@animals < 5) { ... } #译注:当@animals数组的元素个数少于5个的时候

?????当我们从数组获得元素值的时候,需要使用$,因为我们只要获取数组里的一个值;你请求一个标量,然后会获得一个标量。

?????从数组里获取多个值:

?????(译注:获取多个值,使用@,因为我们要获取数组里的几个值(列表)。)

????????1.? @animals[0,1]; # gives("camel","llama");

????????2. @animals[0..2]; # gives ("camel","owl");

????????3. @animals[1..$#animals]; # gives all except the first element

?????这叫“数组切片”。

?????你可以在列表里干些有意义的事情:

????????1.? my @sorted = sort @animals;

????????2. my @backwards = reverse @numbers;

?????有两个特殊的数组,一个是命令行传到你脚本的参数@ARGV;另一个是传递给子程序的参数@_。

???* 哈希

?????哈希用来表示键/值对:

????????1.? my %fruit_color =("apple","red","banana","yellow");

?

?????你可以使用空白字符和=>操作符来美化上面的代码:

????????1.? my %fruit_color = (

????????2. apple => "red",

????????3. banana => "yellow",

????????4. );

?????获取哈希元素:

????????1.?$fruit_color{"apple"}; # gives "red"

?????你可以通过keys()和values()来获取键列表和值列表。

????????1.? my @fruits = keys%fruit_colors;

????????2. my @colors = values %fruit_colors;

?????哈希没有特定的内部排序,然而你可以对键进行排序来遍历它。 和特殊的标量、数组一样,哈希也有特殊的。我们现在只要知道哈希%ENV包括所有环境变量。更复杂的数据类型可以使用引用来构造,允许你把列表和哈希放到另一个列表和哈希中。引用是一个标量值,它可以引用任何其它的Perl数据类型。通过把引用存储为数组或哈希的元素值,你可以轻松创建列表/哈希中的列表/哈希。以下示例演示了使用匿名哈希引用实现的两级哈希结构

??1.? my $variables = {

??2. scalar => {

??3. description => "single item",

??4. sigil => '$',

??5. },

??6. array => {

??7. description => "ordered list of items",

??8. sigil => '@',

??9. },

?10. hash => {

?11. description => "key/value pairs",

?12. sigil => '%',

?13. },

?14. };

?15.

?16. print "Scalars begin with a$variables->{'scalar'}->{'sigil'}n";

变量作用域

上面所有的例子都使用这种语法:

??1.? my $var = "value";

实际上,my不是必须的。你可以省略:(译注:前提是,你没有使用“use strict;”语句)

??1.? $var = "value";

但是,上面的用法将创建一个全局变量,这是一个很差的编程实践。my创建一个词法作用域变量,这个变量只在定义它们的语句块中可见(比如一段包在大括号里的语句)。

??1.? my $x = "foo";

??2. my $some_condition = 1;

?? 3. if ($some_condition) {

??4. my $y = "bar";

??5. print $x; # prints "foo"

??6. print $y; # prints "bar"

??7. }

??8. print $x; # prints "foo"

??9. print $y; # prints nothing; $y has fallen out of scope

结合使用my和在Perl脚本开头使用use strict,解释器将捕获常见的编程错误。比如,在上面的例子中,最后的print $y将引发一个编译时错误并阻止程序运行。强烈建议使用use strict语句!


条件和循环语句

Perl有许多常用的条件和循环语句。Perl 5.10甚至提供了分支语句(拼作given/when)。

条件可以是任何Perl表达式。比较和布尔条件语句中常用的逻辑运算符,请参阅有关信息的下一节中的运算符的列表。

???* if

????????1.? if ( condition ) {

????????2. ...

????????3. } elsif ( other condition ) {

????????4. ...

????????5. } else {

????????6. ...

????????7. }

?????还有否定版本的:

????????1.? unless ( condition ) {

????????2. ...

????????3. }

?????这个否定版比if (!condition)更易读。

?????注意,大括号是必须的,即使代码块中只有一行。不过,这里有一个方法可以让你通过类似英语的语法来实现单行条件语句:

????????1.? # the traditional way

????????2. if ($zippy) {

????????3. print "Yow!";

????????4. }

????????5.

????????6. # the Perlish post-condition way

????????7. print "Yow!" if $zippy;

????????8. print "We have no bananas" unless $bananas;

???* while

????????1.? while ( condition ) {

????????2. ...

????????3. }

?????为了和unless同样的理由,也有一个否定版本:

????????1.? until ( condition ) {

????????2. ...

????????3. }

?????你也可以在后置条件里使用while:

?????print "LA LA LAn" while 1;????????? # loops forever

???* for

?????跟C语言一样:

????????1.? for ($i = 0; $i <= $max;$i++) {

????????2. ...

????????3. }

?????自然Perl提供了更友好的列表遍历循环foreach以后,C语言风格的for循环在Perl几乎不需要了。

???* foreach

????????1.? foreach (@array) {

????????2. print "This element is $_n";

????????3. }

????????4.

????????5. print $list[$_] foreach 0 .. $max;

????????6.

????????7. # you don't have to use the default $_ either...

????????8. foreach my $key (keys %hash) {

????????9. print "The value of $key is $hash{$key}n";

???????10. }

内置操作符和函数

Perl 附带了各种各样的内置函数。我们已经看到的几个,包括print,sort和reverse。

Perl常见操作符(运算符)

???* 算术

????????1.? + 加法

????????2. - 减法

????????3. * 乘法

????????4. / 除法

???* 数字比较

????????1.? == 等于

????????2. != 不等于

????????3. < 小于

????????4. > 大于

????????5. <= 小于等于

????????6. >= 大于等于

???* 字符串比较

????????1.? eq 等于

????????2. ne 不等于

????????3. lt 小于

????????4. gt 大于

????????5. le 小于等于

????????6. ge 大于等于

?????(为什么数字和字符串的比较运算符不同?因为我们没有不同的变量类型,并且Perl需要知道是以数字进行排序(99小于100)还是以字母进行排序(100在99前面))

???* 逻辑

????????1.? && and 和

????????2. || or 或

????????3. ! not 否

???* 混合

????????1.? = 赋值

????????2. . 字符串连接

????????3. x 字符串乘法

????????4. .. 范围 (建立一个列表)

?????一些操作符可以和=结合,像这样:

????????1.? $a += 1; # same as $a = $a + 1

????????2. $a -= 1; # same as $a = $a - 1

????????3. $a .= "n"; # same as $a = $a . "n";

文件和I/O

你可以使用open()函数来打开一个文件,用于输入或输出:

1. open(my $in,"<","input.txt") or die "Can't open input.txt: $!";

2. open(my $out,">","output.txt") or die "Can't open output.txt: $!";

3. open(my $log,">>","my.log") or die "Can't open my.log: $!";

你可以使用<>操作符从打开的文件句柄中读数据。在标量上下文中,它从文件句柄中读取一行;在列表上下文中,它读取整个文件,并将每一行作为列表的元素。

??1.? my $line = <$in>;

??2. my @lines = <$in>;

一次性把整个文件读完,叫做“啜食(slurping)”。它能让人满意,但它可能是内存吞噬者。大多数文本文件处理可以通过Perl的循环结构,一行一行地完成。

?

<>操作符经常出现在while循环里

??1.? while (<$in>) { #assigns each line in turn to $_

??2. print "Just read in this line: $_";

??3. }

我们已经看到了如何使用print()在标准输出里打印。但是,print()还能通过第一个可选参数指定一个文件句柄来打印(译注:将内容输出到指定的文件句柄中,即写入到文件句柄相关联的文件中)

??1.? print STDERR "This isyour final warning.n";

??2. print $out $record;

??3. print $log $logmessage;

当你完成了对文件句柄的操作之后,你应该使用close()来关闭文件句柄。(老实说,如果你忘记关闭了,Perl会帮你处理。)

???close $in or die "$in: $!";

正则表达式

Perl对正则表达式的支持宽广而深入:

???* 简单匹配

????????1.? if (/foo/) { ... } # true if$_ contains "foo"

????????2. if ($a =~ /foo/) { ... } # true if $a contains "foo"

?????//匹配操作符(译注,完整的应该是:m//)默认操作$_,或者使用=~来绑定其它变量进行操作。

???* 简单置换

????????1.? s/foo/bar/; # replaces foowith bar in $_

????????2. $a =~ s/foo/bar/; # replaces foo with bar in $a

????????3. $a =~ s/foo/bar/g; # replaces ALL INSTANCES of foo with bar in $a

???* 更复杂的正则表达式

?????你不仅能匹配固定的字符串。其实,你可以匹配任何你能想到的复杂正则表达式。

????????1.? . 单个任意字符(默认不包含n)

????????2. s 一个空白字符 (空格,tab,换行,...)

????????3. S 一个非空白字符

????????4. d 一个数字 (0-9)

????????5. D 一个非数字

????????6. w 一个能组成单词的字符 (a-z,A-Z,0-9,_)

????????7. W 一个不能组成单词的字符

??? ?????8. [aeiou] 匹配中括号内的任意一个字符

????????9. [^aeiou] 匹配除了中括号内列出的字符之外的任意一个字符

???????10. (foo|bar|baz) 匹配foo或bar或baz

???????11.

???????12. ^ 匹配开头

???????13. $ 匹配结尾

?????量词可用来指定数量:

????????1.? * 零个或任意多个

????????2. + 至少一个

????????3. ? 零个或一个

????????4. {3} 3个

????????5. {3,6} 3到6个

????????6. {3,} 至少3个

?????一些简单的例子:

????????1.? /^d+/ 以一个或多个数字开头

????????2. /^$/ 空的,没有任何东西

????????3. /(ds){3}/ 3个带空白字符的数字

????????4. (比如 "3 4 5 ")

????????5. /(a.)+/ 匹配最少一次,含有a和任意字符

????????6. (比如 "abacadaf")

????????7.

????????8. # 从STDIN循环读入,并打印出非空白行:

????????9. while (<>) {

???????10. next if /^$/;

???????11. print;

???????12. }

???* 圆括号捕捉

?????括号的另一个用法是分组。它可以用来捕捉最后使用的正则表达式匹配的结果。这些结果用$1、$2……表示。

?

????????1.? # a cheap and nasty way tobreak an email address up into parts

????????2.

????????3. if ($email =~ /([^@]+)@(.+)/) {

????????4. print "Username is $1n";

????????5. print "Hostname is $2n";

????????6. }

子程序

写一个子程序是很容易的:

??1.? sub logger {

??2. my $logmessage = shift;

??3. open my $logfile,"my.log" or die"Could not open my.log: $!";

??4. print $logfile $logmessage;

??5. }

现在我们可以像使用其它内置函数一样,使用该子程序了:

??1.? logger("We have a loggersubroutine!");

什么是shift?传递给子程序的参数保存在@_数组中。shift函数的默认参数是@_。所以my $logmessage = shift;去掉第一个参数,并将其赋值给$logmessage。

可以通过别的方法操作@_:

??1.? my ($logmessage,$priority) =@_; # common(通用)

??2. my $logmessage = $_[0]; # uncommon,and ugly(不通过,并且很丑陋)

子程序可以返回值:

#?sub square {

# my $num = shift;

# my $result = $num * $num;

# return $result;

# }

然后像这样使用它:

??1.? $sq = square(8);

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读