Perl学习记录(一)

第一章 简介

一个简单的程序
“Hello,World” 这个程序在Perl里面的写法:
在文本编辑器(如vi)里输入

#!/usr/bin/perl
print "Hello, world!\n";

其中#!在unix系统里表示执行后面跟着的路径程序
如果不清楚路径,可使用#!/usr/bin/envperl自动定位perl路径
另一种写法:
使用use 5.010语句告诉Perl, 我们需要引入5.10该版本中的新特性:

#!/usr/bin/perl
use 5.010;
say "HelloWorld!";

将其改为可执行程序,并执行

chmod 755 first
./first

编译并运行perl程序:

perl my_program

初识perl程序:

#! /usr/bin/perl
@lines = `perldoc -u -fatan2` ;
foreach (@lines) {
    s/\W<([^>]+)>/\U$1/g;
    print;
}

第二章 标量数据

数字

浮点数直接量写法:
1.25
255.000
255.0
7.25e45 # 7.25乘以10的45次方(一个很大的数)
-6.5e24 #负6. 5乘以10的24次方(一个非常大的负数)
-12e-24 #负12乘以10的-24次方 (一个非常小的负数)
-1.2E-23 #另一种表示法:字母E也可以是大写的
整数直接量
0
2001
-40
255
61298040283768
另一种写法:
61_298 _040 283 768
非十进制的整数直接量
八进制(octal) 直接量以o开头,十六进制(hexadecimal) 直接量以ox开头,而二进制(binary) 直接量则以ob开头。十六进制数的A到F (或是小写的a到f也行),代表十进制数的10到15的数字。例如:
0377 #八进制的377,等于十进制的255
0xff #十六进制的FF,也等于十进制的255
011111111 #也等于十进制的255
那么采用哪种写法最能说明问题,我们就该用哪种,
非十进制直接量的长度超过4个字符时,读起来可能会有些困难,也可使用下划线,分开后读起来更容易些:
0x1377
0B77
0x50
65 _72 _7C

数字操作符
2+3 # 2加上3,得5
5.1-2.4 # 5.1减去2.4,得2.7
3*12 # 3乘以12,得36
14/2 # 14除以2,得7
10.2/0.3 # 10.2除以0.3,得34
10/3 #总是按浮点类型进行除法运算,所以得3.333333…
10%3 #取模,10除以3的余结果是1。(取模先取整再求余)
2**3 #代表2的3次方,结果为8

字符串

字符串可以各种字符任意组合而,比如he1lo或者e★ow。最短的字符串不包含任何字符,所以也叫做空字符串。
单引号内的字符串直接量
一对单引号(’) 圈引的一串字符。除了单引号和反斜线字符外,单引号内所有字符都代表它们自己,要表示反斜线字符本身,需要在这个反斜线字符前再加一个反斜线字符表示转义;要表示单引号本身时,同样在单引号前加一个反斜线字符表示转义。
’ fred’ #总共4个字符: f, r. e和d
’ barney’ #总共6个字符
‘’ #空字符串(没有字符)
’ %0¥’ #某些“宽”Unicode字符
‘Don’t 1et an apostrophe end this string prematurely! ’
‘the last character is a backslash: \’
‘hello\n’ #hel10后面接着反斜线和字母n
‘hello
there’ # hello、 换行符、there (总共11个字符)
‘’\’ #单引号紧接着反斜线(总共2个字符)
请注意:单引号内的\n并不是换行符,而是表示字面上的两个字符:反斜线和字母n。只有在反斜线后面接续单引号或者反斜线时,才表示转义。

双引号内的字符串直接量
双引号表示首尾的字符串序列。不过双引号中的反斜线更为强大,可以转义许多控制字符,或是用八进制或十六进制写法来表示任何字符。还是来看一些具体例子:
“barney” #和’barney’写法一样的效果
“hello world\n” # helloworld, 后面接着换行符
"The last character of this string is a quote mark: “”
“coke\tsprite” # coke、制表符(tab)和sprite
“\x{2668}” # 名为HOT SPRINGS的字符的代码点(code point)

表2-1:双引号内字符串的反斜线转义
组合 意义
\n 换行
\r 回车
\t 水平制表符
\f 换页符
\b 退格
\a 系统响铃
\e Esc (ASCII编码的转义字符)
\007 八进制表示的ASCII值(此例中007表示系统响铃)
\x7f 十六进制表示的ASCII值(此例中7f表示删除键的控制代码)
\x{2744} 十六进制表示的Unicode代码点
(这里的U+2744表示雪花形状的图形字符)
\cC 控制符,也就是Control键的代码
( 此例表示同时按下Ctr1键和C键的返回码)
\ 反斜线
\ 双引号
\1 将下个字母转为小写的
\L 将它后面的所有字母都转为小写的,直到\E为止
\u 将下个字母转为大写的
\U 将它后面的所有字母都转为大写的,直到\E为止
\Q 相当于把它到\E之间的非单词(non word)字符加上反斜线转义
\E 结束\L、\U和\Q开始的作用范围

字符串操作符
字符串可以用.操作符(没错,就是句点符号)连接起来。两边的字符串都不会因此操作而被修改,就像2+3的运算不会改变2或3一样。运算后得到一个更长的字符串,可以继续用于其他运算或赋予某个变量。来看具体例子:

"hello" . "world"		#等同于"helloworld"
"hello" . ' '."world"	#等同于'hello world'
'hello world' . "\n"		#等同于"hello world\n"
字符串重复操作符:小写字母x"fred" x 3			#得"fredfredfred"
"barney" x (4+1)	#得"barney" x 5,即"barneybarneybarneybarneybarney"
5x4.8				#本质上就是"5"x4,所以得5555
重复次数在使用前会先取整(4.8变成4) 。重复次数小于1时,会生成长度为零的空字符串。

数字与字符串之间的自动转换
Perl会根据需要自动在数字和字符串之间进行类型转换。取决于操作符。如果操作符(比如+)需要的是数字,Perl就会将操作数视为数字;在操作符(比如.)需要字符串时,Perl便 会将操作数视为字符串。.
对数字进行运算的操作符(比如乘法)如果遇到字符串类型的操作数,Perl会自动将字符串转换成等效的十进制浮点数进行运算。因此"12"*“3"的结果会是36。字符串中非数字的部分(以及空白符号)会被略过,所以"12fred34” *”3"也会得出36,而不会出现任何警告信息。在最极端的情形下,完全不含数字的字符串会被转换成零。

0377				#十进制数字255的八进制写法0377'				 #会转换成十进制数字377
"Z”.5*7 			#等同于"Z".35,得"Z35"

Perl的内置警告信息

当发现程序有些不对劲时,可以让Perl发出警告。

#!/usr/bin/perl
use warnings;

也可以在命令行上使用-w选项对要运行的程序开启警告功能

perl -w my_program

也可以在shebang行上指定命令行选项:
#!/usr/bin/perl -w

现在,如果你把’12fred34’当数字用,PerI就会 发出警告:
Argument “12fred34” isn’t numeric
虽然发出了警告,但Perl仍然会按照它既定的默认规则,把非数字字符串’12fred34’转换为12。
可以利用diagnostics这个编译命令报告更为详尽的问题描述。在perldiag文档中列有简要警告信息和详细诊断说明,该文档是理解
diagnostics输出信息的最佳参考:

#!/usr/bin/perl
use diagnostics;

也可以通过命令行选项-M来实现:

perl -Mdiagnostics . /my_ program

标量变量

所谓变量(variable) ,就是存储一个或多个值的容器的名称。而标量变量,就是单单存储一个值的变量。后续章节我们还会看到其他类型的变量,比如数组和哈希,它们都可以存储多个值。
标量变量的名称以 $ 开头,名称由一个字母或下划线开头,后接
多个字母、数字或下划线。标识符是区分大小写的。
变量 $ Fred和 $ fred是两个完全不同的变量。
$ 的意思是“取单个东西”或者“取标量”

变量的命名
建议以全小写形式,如$line_length形式增加可读性

标量的赋值
赋值操作符为等号=

$fred= 17;	 #将$fred的值设为17
$barney = 'hello';  # 将$barney的值设为5个字符组成的字符串' hello'
$barney=$ fred+3;#将$barney设为$ fred当前值加上3后的结果,即20
$barney = $ barney*2; #被设成$barney当前值乘以2后的结果,即40

双目赋值操作符

$fred = $fred + 5; #不使用双目赋值操作符
$fred += 5;  #使用双目赋值操作符
以下这两行也是等效的:
$barney = $barney * 3;
$barney *= 3;

双目赋值操作符都是以某种方式直接修改变量的值,而非对表达式求值后覆盖原变量值。
另一个常见的双目赋值操作符是由字符串连接操作符(.)改进而成的追加操作符(.=) :

$str = $str. " ";  #在$str末尾追加-一个空格字符
$str .= " ";  #用追加操作符做同样的事
比如,乘幂操作符可以改成**=
$fred**=3  #将$fred里的值自乘3次(也就是取三次方),再存回$fred”。

用print输出结果

print "hello world\n"; #输出hello world,后面接着换行符
print "The answer is";
print 6 * 7;
print ".\n";
你也可以用print输出一系列用逗号隔开的值:
print "The answer is ",6 * 7, ".\n";

字符串中的标量变量内插
标量变量替换成该变量当前的值。比如:

$meal= "brontosaurus steak" ;
$barney = "fred ate a $meal" ;  # $barney现在是" fred ate a brontosaurus steak"
$barney = 'fred ate a ' . $meal;  #另一种等效写法

正如上面最后一行所示,不用双引号也可以达成相同效果,但用双引号写起来更简便清晰。

如果标量变量从未被赋值过,就会用空字符串来替换:
$barney = "fred ate a $meat"; # $barney就会变成"fred ate a"
如果只是要打印这个变量值,则不必使用变量内插的方式:
print "$fred";  #双引号是多余的
print $fred;    #这样写比较好

变量内插又被称为双引号内插,因为它通常是在双引号(而非单引号)里起作用的。
如果要将美元符号本身放进双引号内的字符串,可以在它前面用反斜线转义,以避开它.的特殊意义:

$fred = 'hello';
print "The name is \$fred. \n";   #会输出$符号
当然,也可以跳开这个变量,用串接的方式构造新的字串:
print 'The name is $fred' . "\n";   #效果相同

进行内插时,Perl会尽可能使用最长且合法的变量名称。要是你想在内插的值后面紧接着输出字母、数字或下划线,可能会碰上麻烦。应该使用{ }将变量名围起来,避免歧义。

$what = "brontosaurus steak" ;
$n=3;
print "fred ate $n $whats.\n";  #不是steaks,而是$whats的值
print "fred ate $n ${what}s.\n"; #现在用的是$what的值
print "fred ate $n $what"."s.\n";#另一种写法,但比较麻烦
print 'fred ate ' . $n .' ' . $what."s. \n" ;#特别麻烦的写法

借助代码点创建字符

有时候我们需要输入键盘上没有的那些字符,直接键入这些字符的代码点

$alef= chr( 0x05D0 );
$aIpha= chr( hex('03B1') );
$omega = chr( 0x03C9 );
反过来,我们可以通过ord()函数把字符转换为代码点:
$code_ point=ord('? ');
通过代码点创建的字符同样可用于双引号内的变量内插:
" $aIpha$omega "
如果不预先创建变量,也可以直接在双引号内用\x{}的形式表示,虽然看起来有点眼花,但也还算方便:
"\x{03B1}\x{03C9}"

操作符的优先级与结合性
懒得查直接用括号去优先就行了
操作符的结合性与优先级(从高至低排序)
结合性 操作符
左 括号;给定参数的列表操作符
左 ->
++ – (自增;自减)
右 **
右 \ ! ~ + - (单目操作符)
左 =~ !~
左 * / % x
左 + - .(双目操作符)
左 << >>
具名的单目操作符(-X文件测试; rand)
<<=>>=1tlegtge(“不相等”操作符)
== != <=> eq ne cmp (“相等”操作符)
左 &
左 |^
左 &&
左 ||
……
右 ?: (三目操作符)
右 = += -= .= (以及类似的赋值操作符)
左 , =>
列表操作符(向右结合)
右 not
左 and
左 or xor

比较操作符
表2-3:数值与字符串的比较操作符
比较 数字 字符串
相等 == eq
不等 != ne
小于 < 1t
大于 > gt
小于或等于 <= le
大于或等于 >= ge
来看几个用到这些比较操作符的表达式:

35!=30+5 #假
35 = 35.0 #真
'35’ eq '35.0' #假(当成字符串来比较)
'fred' lt ' barney' #假
'fred' lt ' free' #真
'fred' eq "fred"  #真
'fred' eq ' Fred'  #假
' ' gt '' #真

if控制结构

if条件语句控制结构:

if($name gt 'fred') {
print"'$name' comes after 'fred' in sorted order. \n";
}
如果要在条件不符时做别的处理,可以使用else关键字:
if($namegt' ' fred'){
print "'$name' comes after ' fred' in sorted order. \n";
}else{
print "'$name' does not come after ' fred' . \n";
print "Maybe it's the same string, in fact.\n";
}

布尔值
如果把表达式返回的真假值保存到变量中,那么在判断时可以直接检查该变量的值,读起来也更方便:

$is_ bigger = $name gt' fred';
if ($is_ bigger) {...}

如果是数字,o为假;所有其他数字都为真。
如果是字符串,空字符串("’) 为假;所有其他字符串都为真。
如果既不是数字也不是字符串,那就先转换成数字或字符串再行判断。
字符串’o’跟数字0是同一个标量值,字符串’0’是唯一被当成假的非空字符串。
要取得任何布尔值的相反值,可以用!这个单目取反操作符。若它后面的操作数为真,就返回假;若后面的操作数为假,则返回真:

if (! $is_ bigger) {
#如果$is_ _bigger不为真, 则执行这里的代码
}

由于!会颠倒真假值,并且Perl又没有专门的布尔类型的变量,所
以!总是会返回某个代表真假的标量值。而数字1和undef都是非常自然的表示真假的标量值,所以人们常常喜欢把布尔值归一化到这两个值来表示。转换过程只是利用了连续两次的!反转操作,得到表示布尔值的变量:

$still_ .true = !! 'Fred';
$still_ false = !! '0';

获取用户输入

“行输入”操作符
只要把放在程序中希望返回标量值的位置上,Perl就会从标准输入(standard input)读取一行文本(直到换行符为止)。
由返回的字符串- -般在末尾都会带有换行符

$line = <STDIN>;
if ($line eq "\n") {
print "That was just a blank line!\n";
} else {
print "That line of input was: $line" ;
}

不过实际编写代码时,很少需要保留末尾换行符,所以人们常常会用chomp()操作符去掉它。

chomp操作符

去除变量字符串末尾的换行符

$text ="a line of text\n"; #或者从<STDIN>读进来
chomp($text); #去除行末的换行符

chomp()最 常见的用法就是连用:

chomp($text=<STDIN>); #读人文字,略过最后的换行符
$text = <STDIN>;#做同样的事却被分为两步......
chomp($text);

while控制结构

在while循环中,只要条件持续为真,就会不断执行代码块:

$count = 0;
while ($count < 10) {
$count += 2;
print "count is now $count\n"; #依次打印值246810
}

undef值

在首次赋值前,变量的初始值就是特殊的undef(未定义)值,它在Perl里的意思仅仅是:这里空无一物—走开、走开。如果你想把
这个“空无一物”当成数字使用,它就会表现得像零;如果当成字符串使用,它就会表现得像空字符串。但undef既不是数字也不是字符串,它完全是另一种类型的标量值。
既然undef作为数字时会被视为零,我们可以很容易地构造一个数字累加器,它在开始时是空的:

#累加一些奇数
$n=1;
while ($n < 10) {
$sum += $n;
$n += 2; #准备下一个奇数
print. "The total was $sum.\n" ;

在循环开始之前,$ sum的初始值是undef,但这并不妨碍程序的运行。当第一次执行循环时,$n的值是1,所以循环里的第一行会将 $ s um的值加上1。这么做,如同将现值为0的变量加1 (因为我们把undef当成数字用),所以累加的值会变成1。此后它已经被初始化
了,所以就能按常规方式累加。同样的道理,也可以做出一个字符串累加器,它在一-开 始时是空的:

$string .= "more text\n" ;

如果$string的初始值是undef,它在这里就会被当成空字符串处理,变量的值被设为"moretext\n"。如果它里面已经有字符串,就会把新的文字追加在后面。
Perl程序员常常根据需要把新变量当作零或空字符串来用。

defined函数

行输入操作符有时候会返回undef。在一般状况下,它会返回一行文本。但若没有更多输入,比如读到文件结尾(end-offile) 时,它就会返回undef来表示这个状况;
要判断某个字符串是undef而不是空字符串,可以使用defined函数。如果是undef, 该函数返回假,否则返回真:

$madonna = <STDIN>;
if ( defined($madonna) ) {
print "The input was $madonna" ;
} else {
print "No input availablel\n";
}

习题

1.[5]写一个程序,计算在半径为12.5时,圆的周长应该是多少。圆周长是半径的长度乘上2T(大约是2乘以3.141592654)。计算结果大约是78.5。
1
参考答案:

#!/usr/bin/perl
$pi = 3.141592654;
$circ = 2 * $pi *12.5;
print "the circumference of a circle of radius 12.5 is $circ . \n";

2.[4]修改上题的程序,让它提示用户键入半径的长度。当用户键入12.5时,出来的计算结果应该和上题相同。
2
参考答案:

#!/usr/bin/perl
$pi = 3.141592654;
print "what is the radius?";
chomp($radius = <STDIN>);
$circ = 2 * $pi *$radius;
print "the circumference of a circle of radius $radius is $circ . \n";

注:除非有特殊要求,不然对输入值记得做chomp操作!!!

3.[4]修改上题的程序,当用户键入小于0的半径时,输出0,而不是负数。
3
参考答案:

#!/usr/bin/perl
$pi = 3.141592654;
print "what is the radius?";
chomp($radius = <STDIN>);
$circ = 2 * $pi *$radius;
if$radius < 0{
$circ = 0 }
print "the circumference of a circle of radius $radius is $circ . \n";

4.[8]写一个程序,提示用户键入两个数字(分两行键入),然后输出两者的乘积。
4
参考答案:

#!/usr/bin/perl
print "enter first number:"
chomp($one = <STDIN>);
print "enter second number?";
chomp($two = <STDIN>);
$result = $one * $two ;
print "the result is $result . \n";

5.[8]写一个程序,提示用户键入一个字符串及一个数字(分两行键入),然后以数字为重复次数,连续输出字符串(提示:使用x操作符)。在用户键入“fred”和“3”时,应该会输出3行“fred”;如果用户键入的是“fred”与“299792”,输出结果应该是一大堆。
5
参考答案:

print "enter a sting";
$str = <STDIN>;
print "enter a number of times";
chomd($num = <STDIN>);
$result = $str x $num;
print "the result is : \n$result";

注意:x与前面变量一定中间要有空格

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值