⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 perlprogramingprimer.txt

📁 perl编程初级教程! 详细的讲解了
💻 TXT
📖 第 1 页 / 共 2 页
字号:

但是如果我们把这个句子赋值给特殊变量$_,用起来会更容易些。如果这样,我们可以避免使用匹配和非匹配操作符,上面的例子可以写成:
if (/under/)
{
	print "We're talking about rugby\n";
}

$_变量是很多Perl操作的缺省变量,经常被使用。

其它的RE

在RE中有大量的特殊字符,既使它们功能强大,又使它们看起来很复杂。最好在用RE时慢慢来,对它们的使用是一种艺术。

下面是一些特殊的RE字符和它们的意义:
.	# Any single character except a newline
^	# The beginning of the line or string
$	# The end of the line or string
*	# Zero or more of the last character
+	# One or more of the last character
?	# Zero or one of the last character

下面是一些匹配的例子,在使用时应加上/.../:
t.e	# t followed by anthing followed by e
	# This will match the
	#                 tre
	#                 tle
	# but not te
	#         tale
^f	# f at the beginning of a line
^ftp	# ftp at the beginning of a line
e$	# e at the end of a line
tle$	# tle at the end of a line
und*	# un followed by zero or more d characters
	# This will match un
	#                 und
	#                 undd
	#                 unddd (etc)
.*	# Any string without a newline. This is because
	# the . matches anything except a newline and
	# the * means zero or more of these.
^$	# A line with nothing in it.

还有更多的用法。方括号用来匹配其中的任何一个字符。在方括号中"-"表明"between","^"表示"not":
[qjk]		# Either q or j or k
[^qjk]		# Neither q nor j nor k
[a-z]		# Anything from a to z inclusive
[^a-z]		# No lower case letters
[a-zA-Z]	# Any letter
[a-z]+		# Any non-zero sequence of lower case letters

上面提到的已经基本够用了,下面介绍的只做参考:

竖线"|"表示"or",括号(...)可以进行集合:
jelly|cream	# Either jelly or cream
(eg|le)gs	# Either eggs or legs
(da)+		# Either da or dada or dadada or...

下面是一些其它的特殊字符:
\n		# A newline
\t		# A tab
\w		# Any alphanumeric (word) character.
		# The same as [a-zA-Z0-9_]
\W		# Any non-word character.
		# The same as [^a-zA-Z0-9_]
\d		# Any digit. The same as [0-9]
\D		# Any non-digit. The same as [^0-9]
\s		# Any whitespace character: space,
		# tab, newline, etc
\S		# Any non-whitespace character
\b		# A word boundary, outside [] only
\B		# No word boundary

象$, |, [, ), \, /这样的字符是很特殊的,如果要引用它们,必须在前面加一个反斜线:
\|		# Vertical bar
\[		# An open square bracket
\)		# A closing parenthesis
\*		# An asterisk
\^		# A carat symbol
\/		# A slash
\\		# A backslash

RE的例子

我们前面提到过,用RE最好慢慢来。下面是一些例子,当使用它们时应方在/.../中。
[01]		# Either "0" or "1"
\/0		# A division by zero: "/0"
\/ 0		# A division by zero with a space: "/ 0"
\/\s0		# A division by zero with a whitespace:
		# "/ 0" where the space may be a tab etc.
\/ *0		# A division by zero with possibly some
		# spaces: "/0" or "/ 0" or "/  0" etc.
\/\s*0		# A division by zero with possibly some
		# whitespace.
\/\s*0\.0*	# As the previous one, but with decimal
		# point and maybe some 0s after it. Accepts
		# "/0." and "/0.0" and "/0.00" etc and
		# "/ 0." and "/  0.0" and "/   0.00" etc.

第三页:替换和翻译

Perl可以在匹配的基础上进行替换操作。可以用s函数实现这个功能。如果不使用匹配操作符,那么替换被认为对$_变量进行操作。

在字符串$sentence中用London替换london可以用下面的表达式:

$sentence =~ s/london/London/

用$_变量可以这样做:

s/london/London/

表达式的结果是替换发生的次数,所以或者是0或者是1。

选项

上面的例子只替代第一个匹配的字符串,用g参数可以进行全程替换:

s/london/London/g

返回的结果为0或被替换的次数。

如果我们想替换lOndon, lonDON, LoNDoN等,可以这样做:

s/[Ll][Oo][Nn][Dd][Oo][Nn]/London/g 

但是可以有更简单的方式 - 使用i选项(忽略大小写):

s/london/London/gi

记忆方式

如果记住匹配方式,以后用起来可以更方便。任何发生在括号内的匹配被记在变量$1,...,$9中。这些用在相同RE中的字符串可以用\1,...,\9表示:
$_ = "Lord Whopper of Fibbing";
s/([A-Z])/:\1:/g;
print "$_\n";

这段代码替换任何大写字母为被冒号包围的形式。结果是:L:ord :W:hopper of :F:ibbing。变量$1,...,$9是只读变量,不可以修改它们。

另一个例子,判断语句:
if (/(\b.+\b) \1/)
{
	print "Found $1 repeated\n";
}

将判断任何重复的单词。每个\b代表一个单词边界,.+与任何非空字符串相匹配,因此\b.+\b匹配任何两个单词边界中的内容。然后被括号记住,存储在\1中,$1被程序的其余部分使用。

下面的表达式交换$_变量的第一个和最后一个字符:

s/^(.)(.*)(.)$/\3\2\1/

^和$匹配行的开始和结尾。\1存储第一个字符,\2存储除第一个和最后一个字符之外的部分,最后一个字符存储在\3中。然后\1和\3进行互换。

匹配之后,可以使用特殊的只读变量$~、$&和$'找到查询之前、之中和之后的内容。所以在
$_ = "Lord Whopper of Fibbing";
/pp/;

之后,下面的表达式都为真(eq表示字符串匹配判断)。
$` eq "Lord Wo";
$& eq "pp";
$' eq "er of Fibbing";

在替换表达式中可以使用变量,因此
$search = "the";
s/$search/xxx/g;

将把任何出现的the替换为xxx。如果想替换there,则不能使用s/$searchre/xxx/,因为程序会把它当作变量$searchre。可以用花括号实现there的替换:
$search = "the";
s/${search}re/xxx/;

翻译

tr函数实现字符对字符的翻译。下面的表达式替换变量$sentence中的每个a为e,b为d,c为f。表达式返回替换的次数。

$sentence =~ tr/abc/edf/

大多数特殊RE代码不能用在tr函数中。例如,下面的语句计算$sentence变量中的星号数,然后存储在变量$count中。

$count = ($sentence =~ tr/*/*/);

但是"-"仍然表示"between"。下面的语句把变量$_转换为大写形式:

tr/a-z/A-Z/;

Perl初级教程 - 第四天

第一页:Split

Perl中的一个非常有用的函数是split - 把字符串进行分割并把分割后的结果放入数组中。这个函数使用规则表达式(RE),如果未特定则工作在$_变量上。

split函数可以这样使用:
$info = "Caine:Michael:Actor:14, Leafy Drive";
@personal = split(/:/, $info);
其结果是: 
@personal = ("Caine", "Michael", "Actor", "14, Leafy Drive");

如果我们已经把信息存放在$_变量中,那么可以这样:

@personal = split(/:/);

如果各个域被任何数量的冒号分隔,可以用RE代码进行分割:
$_ = "Capes:Geoff::Shot putter:::Big Avenue";
@personal = split(/:+/);

其结果是

@personal = ("Capes", "Geoff", "Shot putter", "Big Avenue"); 

但是下面的代码:
$_ = "Capes:Geoff::Shot putter:::Big Avenue";
@personal = split(/:/);

的结果是
@personal = ("Capes", "Geoff", "", "Shot putter", "", "", "Big Avenue"); 

单词可以被分割成字符,句子可以被分割成单词,段落可以被分割成句子:
@chars = split(//, $word);
@words = split(/ /, $sentence);
@sentences = split(/\./, $paragraph);

在第一句中,空字符串在每个字符间匹配,所以@chars数组是一个字符的数组。

第二页:关联数组

顺序表数组允许我们按照数字对其元素进行访问。数组@food的第一个元素是$food[0],第二个元素是$food[1],等等。但是Perl也允许我们建立可以通过字符串进行访问的数组,称为关联数组(associative arrays)。

我们用括号定义关联数组,但是数组名前有一个%符号。假设我们建立一个关于人和他们的年龄的数组,则可以这样:
%ages = ("Michael Caine", 39,
         "Dirty Den", 34,
         "Angie", 27,
         "Willy", "21 in dog years",
         "The Queen Mother", 108);

现在我们可以这样找到人们的年龄:
$ages{"Michael Caine"};		# Returns 39
$ages{"Dirty Den"};		# Returns 34
$ages{"Angie"};			# Returns 27
$ages{"Willy"};			# Returns "21 in dog years"
$ages{"The Queen Mother"};	# Returns 108

访问单个元素时用$,而不是% - 因为单个元素是标量。关联数组的索引包含在花括号内。

可以通过把关联数组赋给一个表数组变量把关联数组转换为表数组。表数组也可以转换为关联数组 - 通过把它赋值给关联数组变量。理想地,表数组将有偶数个元素:
@info = %ages;		# @info is a list array. It
			# now has 10 elements
$info[5];		# Returns the value 27 from
			# the list array @info
%moreages = @info;	# %moreages is an associative
			# array. It is the same as %ages

操作符

关联数组的元素没有顺序(有点象hash表),但是可以通过keys函数和values函数轮流访问所有的元素:
foreach $person (keys %ages)
{
	print "I know the age of $person\n";
}
foreach $age (values %ages)
{
	print "Somebody is $age\n";
}

当keys被调用时,返回关联数组的keys的列表。当values被调用时,返回数组的值的列表。这两个函数返回的列表的顺序相同,但是这个顺序与元素被输入的顺序没有关系。

当keys和values在一个标量环境中被调用时,它们返回关联数组中的key/value对的数目。

有一个each函数返回一个关键字和其值的两个元素的列表。每调用each一次,它返回另一个key/value对:
while (($person, $age) = each(%ages))
{
	print "$person is $age\n";
}

环境变量

当在UNIX中运行perl程序或任何script时,会遇到某些环境变量。比如,USER包含你的用户名,DISPLAY确定图形使用的屏幕。当在WWW中运行perl CGI script时,也有环境变量存储其它有用的信息。所有这些变量和它们的值存储在关联数组%ENV中,其关键字为变量名。可以试试这个perl程序:
print "You are called $ENV{'USER'} and you are ";
print "using display $ENV{'DISPLAY'}\n";

第三页:子过程

和很多语言一样,Perl允许用户定义自己的函数,称为子过程(subroutine)。它们可以放在程序的任何地方,但是最好把它们全放在程序的顶部或尾部。

子过程的形式如下:
sub mysubroutine
{
	print "Not a very interesting routine\n";
	print "This does the same thing every time\n";
}

可以给子过程传递任何数量的参数。下面的语句都可以调用这个子过程。注意子过程在调用时在名称前使用一个&字符:
&mysubroutine;		# Call the subroutine
&mysubroutine($_);	# Call it with a parameter
&mysubroutine(1+2, $_);	# Call it with two parameters

参数

在上面的例子中参数被接受但是被忽略。当子过程被调用时,任何参数都被传递到特殊表数组变量@_中,这个变量与$_没有任何关系。下面的子过程只是打印它被调用的参数的列表。后面是一些调用它的例子。 
sub printargs
{
	print "@_\n";
}

&printargs("perly", "king");	# Example prints "perly king"
&printargs("frog", "and", "toad"); # Prints "frog and toad"

和任何其它列表数组一样,@_中的单个元素可以通过方括号访问:
sub printfirsttwo
{
	print "Your first argument was $_[0]\n";
	print "and $_[1] was your second\n";
}

要注意的是标量$_[0]和$_[1]等与标量$_没有任何关系。

返回值

子过程的结果总是最后被赋值。下面的子过程返回其两个输入参数中较大的,然后是一个调用这个子过程的例子。
sub maximum
{
	if ($_[0] > $_[1])
	{
		$_[0];
	}
	else
	{
		$_[1];
	}
}

$biggest = &maximum(37, 24);	# Now $biggest is 37

上面的&printfirsttwo子过程也返回一个值,这时是1。这是因为这个子过程所做的最后一件事是print语句,打印成功的结果总是1。

局部变量

@_变量对当前子过程是局部的,当然$_[0]、$_[1]、$_[2]等也是这样。其它变量也可以被设置为局部的,这在我们开始改变输入参数时是有用的。下面的子过程判断一个字符串是否在另一个中,不包括空格。然后是一个引用它的例子。
sub inside
{
	local($a, $b);			# Make local variables
	($a, $b) = ($_[0], $_[1]);	# Assign values
	$a =~ s/ //g;			# Strip spaces from
	$b =~ s/ //g;			#   local variables
	($a =~ /$b/ || $b =~ /$a/);	# Is $b inside $a
					#   or $a inside $b?
}

&inside("lemon", "dole money");		# true

实际上,可以简化为

local($a, $b) = ($_[0], $_[1]);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -