2.Perl基础系列之入门

时间:2023-03-09 05:51:10
2.Perl基础系列之入门

官网提供的入门链接:http://perldoc.perl.org/perlintro.html

语法概述

  • Perl的安装步骤省略,直接去官网下载并按照提示安装即可。
  • 如果Perl安装没问题,那么运行一个Perl脚本的步骤是在命令行中输入:

perl progname.pl

其中progname.pl是相应的Perl脚本。

  • 脚本的开头通常包含以下两行,第一行使得脚本运行过程中遇到问题时可立即停止在相应的位置,第二行将在遇到问题的地方给出一个warning。

use strict;

use warnings;

  • Perl语句与很多语言一样,以半角分号;作为结尾。
  • 注释符:#
  • 在双引号中加变量,而不是单引号,如:

print "Hello, $name\n";

变量类型

  • Perl有三种主要的变量类型:scalars,arrays,hashes,分别是标量、数组、哈希。
  • Scalar用于表示一个值,可以是字符串、整型或浮点型,以$作为开头。

my $animal = "camel";

my $answer = 42;

  • Scalar在第一次使用时需要用关键字my进行声明(use strict里规定的):

my $animal;

  • $_可表示默认变量,作为函数的默认参数,如读取文本文件时,每一行可以用$_表示。
  • Array用于表示一系列的值,这些值也可以是任意类型,以@作为开头,需要注意的是数组为0索引:

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

print $animals[0]; # prints "camel"

  • $#animals表示数组animals的最后一个元素的索引,上面这个例子的结果为2,即对应"owl",因此数组数目可用$#animals+1表示,用法如下:

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

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

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

  • 数组排序或反转:

my @sorted = sort @animals;

my @backwards = reverse @numbers;

  • 特别的数组:@ARGV,命令行参数;@_,传递到子函数的参数。
  • Hash用于表示一组键值对,以%作为开头,下面的例子中,%fruit_color表示一个哈希,apple和banana对应哈希的键(key),red和yellow对应哈希的值(value)。

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

  • 更清晰的写法是:

my %fruit_color = (

apple => "red",

banana => "yellow",

);

  • 获取某个键对应的值:

$fruit_color{"apple"}; # gives "red"

  • 也可以获取一组键或一组值,以数组的方式存储:

my @fruits = keys %fruit_colors;

my @colors = values %fruit_colors;

  • 特别的哈希:%ENV,包含环境变量。

变量作用域

  • 变量的声明时,在变量的前面加my表示该变量为局部变量,仅在代码块(如花括号中)起作用,不加my表示该变量为全局变量,在整个代码中均存在。如果my使用不恰当,如在代码块外使用代码快内声明的局部变量,则会报错(使用strict后)。

条件和循环结构

  • if条件判断

if ( condition ) {

...

} elsif ( other condition ) {

...

} else {

...

}

  • 还可以这样表示if (!condition):

unless ( condition ) {

...

}

  • 上面两种方法中,if或unless后面必须包括花括号,下面是单行的写法:

# the traditional way

if ($zippy) {

print "Yow!";

}

# the Perlish post-condition way

print "Yow!" if $zippy;

print "We have no bananas" unless $bananas;

  • while循环:

while ( condition ) {

...

}

  • 也可以这样表示while(!condition):

until ( condition ) {

...

}

  • while的单行写法:

print "LA LA LA\n" while 1; # loops forever

  • for循环,写法与C语言相同:

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

...

}

  • foreach在Perl中更常用:

foreach (@array) {

print "This element is $_\n";

}

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

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

foreach my $key (keys %hash) {

print "The value of $key is $hash{$key}\n";

}

  • Hash按key排序:

foreach my $key (keys sort %hash) {

print "The value of $key is $hash{$key}\n";

}

内置运算符与函数

  • 算术:

+ addition

- subtraction

* multiplication

/ division

  • 数值比较:

== equality

!= inequality

< less than

> greater than

<= less than or equal

>= greater than or equal

  • 字符串比较:

eq equality

ne inequality

lt less than

gt greater than

le less than or equal

ge greater than or equal

  • 布尔逻辑,下面两列都可以表示:

&& and

|| or

! not

  • 其它:

= assignment

. string concatenation

x string multiplication

.. range operator (creates a list of numbers or strings)

  • 为什么要把数值比较和字符串比较分开:Perl没有指明变量类型,例如,在比较99和100时,Perl需要对它们进行排序,然而,若按数值排序,100>99,但按字母表排序,100在99的前面(1<9)。

文件与输入输出

  • 运算符<表示输入,>表示输出,>>表示追加:

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

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

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

  • scalar变量:逐行读取,array变量:一次性全部读取(占用很多内存):

my $line = <$in>;

my @lines = <$in>;

  • 通常用while循环逐行读取:

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

print "Just read in this line: $_";

}

  • 输出到文件:

print STDERR "This is your final warning.\n";

print $out $record;

print $log $logmessage;

  • 文件句柄访问结束后,通常需要关掉,但其实Perl会帮你做这件事情的,以防你忘记(好有爱),但为了统一最好还是要加上close:

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

正则表达式

  • Perl最强大的莫过于对正则表达式的有力支持了,可在perlrequick、perlretut和perlre中详细了解,下面只是简单描述。
  • 简单的匹配(match),//表示匹配运算符:

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

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

  • 简单的替换(substitution),s///表示替换运算符,后面加g表示替换所有:

s/foo/bar/; # replaces foo with bar in $_

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

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

  • 更复杂的正则表达式,可匹配不同的字符串:

. a single character

\s a whitespace character (space, tab, newline, ..)

\S non-whitespace character

\d a digit (0-9)

\D a non-digit

\w a word character (a-z, A-Z, 0-9, _)

\W a non-word character

[aeiou] matches a single character in the given set

[^aeiou] matches a single character outside the given set

(foo|bar|baz) matches any of the alternatives specified

^ start of string

$ end of string

  • 匹配数目:

* zero or more of the previous thing

+ one or more of the previous thing

? zero or one of the previous thing

{3} matches exactly 3 of the previous thing

{3,6} matches between 3 and 6 of the previous thing

{3,} matches 3 or more of the previous thing

  • 一些简单的例子:

/^\d+/ string starts with one or more digits

/^$/ nothing in the string (start and end are adjacent)

/(\d\s){3}/ three digits, each followed by a whitespace character (eg "3 4 5 ")

/(a.)+/ matches a string in which every odd-numbered letter is a (eg "abacadaf")

  • 去空行:

# This loop reads from STDIN, and prints non-blank lines:

while (<>) {

next if /^$/;

print;

}

  • 捕捉:

# a cheap and nasty way to break an email address up into parts

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

print "Username is $1\n";

print "Hostname is $2\n";

}

子函数

  • 子函数格式:

sub logger {

my $logmessage = shift;

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

print $logfile $logmessage;

}

  • 调用子函数:

logger("We have a logger subroutine!");

  • 上面的shift是什么?子函数的参数可以是一个特殊的数组@_,shift函数的默认参数恰好是@_。@_还可以这样用:

my ($logmessage, $priority) = @_; # common

my $logmessage = $_[0]; # uncommon, and ugly

  • 子函数也可以返回值:

sub square {

my $num = shift;

my $result = $num * $num;

return $result;

}

  • 可返回值的子函数用法如下:

$sq = square(8);

以上便是Perl入门需要掌握的一些基础了,这份入门材料只是简化版本,在实际工作中用到哪些知识再进行搜索就行,Perldoc还是挺全面的。

后面我也会更新一些工作中用到的知识。

joey_suAT163.com

2015/11/14