• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    公众号

Perl语法-基础

原作者: [db:作者] 来自: [db:来源] 收藏 邀请

perl语言的核心是正则表达式,在文本处理上非常有优势,与python类似,但语法不同,perl的语法很灵活,用多了才会觉得好用。

常用知识点总结:

  • perl语法类似于C语言(perl源于Unix),语句由逗号划分,代码层次使用花括号{}划分,但是不必声明变量类型;
  • 标量变量($name),数组(@name),哈希结构(%name),类型标识符,文件句柄没有标识符;
  • 哈希结构可以使用列表创建,但不要以为它也是由圆括号括起来的;在使用键时,用花括号。(特别注意)
  • 数字之间比较用(==、>=、<=、!=),字符串之间比较则用(eq、gt、lt、ge、le)
  • print函数,不一定需要括号。几种情况:print \$name(直接输出) ;print ‘\$name’(基本不用,错误的,原样输出);          print “\$name”(有时会用,会自动替换); print 函数在做文件输入时(文件句柄),不能有逗号,只能用空格。
  • @_ 是函数传参时放置参数的数组,可以从中取实参;\$_ 是默认参数的意思,指的是在不指定的情况下,程序处理的上一个变量;shift 是将数组的第一个元素 \$array[0] 移走, 并将这个元素回传(return) (堆栈一节有详细讲解)。
  • shift函数是取数组的第一个元素,缺省就取@_的第一个函数,这句一般用在程序的开头,用于接收程序的参数,或者子函数的开头,用于接收子函数的参数。
  • 句柄和文件的关系,文件必须被打开,并赋与句柄,才能操作;有的句柄可以直接使用,如STDIN、STDERR;广义上,标量变量就是一种代表数据的句柄。
  • perl中数值和字符串可以随意的使用递增和递减运算符。

 

第1学时 P e r l 入门


  • 安装perl
  • perl内部文档
  • 第一个perl脚本

通用编程语言,胶水语言,perl擅长将其他程序连接到一起。

# 检查perl是否安装成功
perl -v

ActiveState Tool公司提供了一个自行安装Perl的工具(安装十分简单)。

# 在Linux下安装perl
# 解压 tar -zxvf stable.tar.gz -C dir
$ gunzip stable.tar.gz
$ tar xf stable.tar
# 配置
$ sh Configure
# 安装
$ make
$ make test  #测试是否make成功
# make install

安装文件有完整的perl帮助文档

perldoc perl

perl手册分如下三个部分:

  • perlfunc
  • perlop
  • perlfaq

perl perlfunc

# 查找某个函数名
perldoc -tf print
# 搜索FAQ文件
perldoc -q support

各人不推荐在命令行窗口查阅文档,阅读模式太不友好,可以阅读HTML格式文档。

可以在浏览器中打开本地HTML文档:file:///D:/Program%20Files/Perl64/html/index.html

#第一个perl程序
#!/usr/bin/perl -w
print "Hello, World!\n";

#运行perl脚本
perl test.pl

linux下可以以可执行文件形式运行perl脚本,但首先必须修改权限,使其可执行。

chmod 755 test.pl
./test.pl

 

第2学时 P e r l 的基本构件:数字和字符串

  • 标量常量:数字 和 字符串
  • 标量变量:存放标量,

字符串

只有使用转义字符才能在字符串中插入特殊的字符。

  • 单引号:‘ ’中的每个字符都表示它本身,$a, \n等等,都不会进行处理,原样输出
  • 双引号:“ ”中Perl会查看是否存在 变量名 和 转义序列,一旦发现,会自动替换

如何便捷的将字符串用 双引号 或 单引号 括起来?

  • qq运算符:qq(I said, “I love you!”)   用法如上
  • q运算符: q(Tom’s tree)   用法与之前单引号一样,会原样输出单引号内的所有内容。

标量变量

特殊变量($_):当前默认值,

运算符(运算符之间可以有空格)

数字运算符有哪些?  

加+;减-;乘*;除/;求余%;取幂**;

字符串运算符有哪些?  

  • 并置运算符(.)(运算对象必须为字符串标量或者标量变量);
  • 可以使用反斜杠\,指定屏蔽字符串内的内插替换(标量变量和转义字符);
  • 如果字符串中标量名和字符串过于紧密,可以用{}显示指定变量名,如${name}space;
  • 重复运算符(x),如“-”x 10;

带名字运算符?

int(5.20); length(“nose”); lc(“ME TOO”); uc(“hal 9000”); cos(50); rand(5)(返回随机浮点数,默认是0-1)

尖括号运算符?

用于读写文件,<STDIN>,从标准输入读入一行;默认会读入我们最后输入的回车,可以使用从chomp运算符去掉;

chomp可以去除任何参数结尾的换行符,返回被删除的字符数(删除了返回1,没删除返回0)。

 

第3学时 控制程序流 (foreach是核心)

  • 语句块
  • 运算符
  • 循环
  • 标号
  • 退出perl

if语句(几乎与C语言类似,除了elsif)

$r = 10;
if ($r == 10){
    print '$r is 10!';
}
elsif ($r == 20){
    print '$r is 20!';
}
else{
    print '$r is neither 10 nor 20.'
}

# 如果只有一个条件可以把if放到后面
print "Hello!" if (1 == 1);

字符关系运算符(类似于=, >, <, >=, <=, !=)?  

  • eq等于;
  • gt大于;
  • lt小于;
  • ge大于等于;
  • le小于等于;
  • ne不等于;

perl中有哪些假值?  0;“”;‘’;‘0’;“0”;undef;

逻辑运算符有哪些?  and; or; not;

if ($x and $y and not $z){
    print "All conditions met.\n";
}else{
    print "Not all.\n"
}

逻辑运算符短路,即一旦确定表达式是真或假,就立即停止逻辑表达式的计算,最常见的是

open(FILE, "test.txt") or die "can't open file:$!\n";

 

循环语句(与C语言完全相同)

$count = 0;
while($count <= 10){
    print "$count\n";
    $count++;
}

for($i; $i <= 10; $i++){
    print "i is now $i\n";
}

#  高级perl技巧:使用foreach进行遍历
@name = qw(li zhi xin);
print "my name is ";
foreach $name (@name){  # $name是对@name中元素的引用,可以修改@name
    print "$name "
}

 

流程控制工具

last语句(退出当前循环)(等同于C里的break)

$count = 1;
while($count <= 15){
    last if ($count == 5);
    print "$count\n";
    $count++;
}

for($i=0; $i <= 100; $i++){
    for($j=0; $j <= 100; $j++){
        if ($i * $j == 140){
            print "The product of $i and $j is 140.\n";
            last;
        }
    }
}

next语句(回到当前循环头部)(等同于C里的continue)

for($i=0; $i <= 100; $i++){
    next if (not $i % 2);
    print "An odd number = $i\n";
}

语句块和循环语句可以设置标号,last、redo 和 next都可以带一个标号。(等价于C的loop语句)

退出perl?  exit 0;代表正常退出perl。

 

第4学时 基本构件的堆栈:列表与数组

  • 填充和清空数组
  • 逐个元素查看数组
  • 对数组进行排序和输出
  • 标量分割为数组
  • 数组合并为标量

列表是常量,数组是变量,可以将列表存放在数组当中。如:

12,’abc‘,3.14,True)   # 这是一个直接量列表

如果列表中全部是字符串,为了避免注意添加单引号,可以使用qw运算符,如

# 两者等价,最好不要有内嵌变量
@a = qw(abc def ghi)  
@b = ('abc','def','ghi')
@c = ()

列表的范围运算符(..)

@a = (1..10)
@b = (1..10, 21..30)
# 字符照样可以使用范围运算符
@list=(aa..zz);
foreach (@list){
    print "$_ ";
}

为什么要把列表这个东西单独拿出来?

因为列表是有特殊作用的常量,可以对其他结构进行初始化(数组和哈希)。

数组(列表)之内的数组会自动合并成一个大的数组。

可以利用数组的特性进行批量赋值

($a, $b, $c) = qw(li zhi xin);

如何从数组中获取元素?

@name=qw(li zhi xin);
print @name;  #没有空格
print "\n@name\n"; #元素之间有空格
print scalar(@name);  #输出数组元素个数

@a = qw(li zhi xin);
print @a;   #  每个数组元素之间紧密排列,没有空格和换行

@a = qw(li zhi xin);
print $a[0];
print $a[1];
print "\n";
$a[2] = "wei";
print @a;

如何将数组划分成片?

@a = qw(li zhi xin 1 2 3 4 5 6);
@b = @a[2,4,6];
print @b;

如何寻找数组的结尾?

@a = qw(li zhi xin 1 2 3 4 5 6);
print $#a;   # 返回结尾元素的索引

@a = qw(li zhi xin 1 2 3 4 5 6);
$size = @a;
print $size;   #根据上下文,返回数组元素的个数

print $a[-1];   #  返回数组的最后一个元素

如何测试数组中是否包含元素?

@mydata = qw(li zhi xin);
if (@mydata){
    print "Not empty!\n";
}

上下文

  • 标量上下文
  • 列表上下文

强制使参数成为上下文?

print scalar(@mydata);   #  scalar( )函数

$a = <STDIN>;  # 读入一行
@whole = <STDIN>;  # 读入整个
($a) = <STDIN>;   # 全部读取,但只保存一行到$a

@stars = ('*') x 10;
foreach $star (@stars){
    print "$star\n";
}

print scalar(localtime);

chomp:标量下,去除标量结尾记录分隔符;列表下,去除每个标量结尾记录分隔符。<STDIN>同理。

对数组进行操作

如何遍历?

#  普通方法:使用for循环进行遍历
@name = qw(li zhi xin);
print "my name is ";
for ($index = 0; $index < @name; $index++){
    print "$name[$index] ";
}

#  高级perl技巧:使用foreach进行遍历
@name = qw(li zhi xin);
print "my name is ";
foreach $name (@name){  # $name是对@name中元素的引用,可以修改@name
    print "$name "
}

foreach遍历时,标量为列表元素的引用,可以同时修改数组(列表)中的元素。

数组和标量之间进行转换?

split函数,拥有一个模式和一个标量,可以使用模式来分割标量。

join函数,去除一个字符串和一个数组(列表),使用该字符串将数组中的元素连接起来。

@word = split(/ /, "The quick brown fox");
foreach $word (@word){
    print "$word\n"
}

$numbers=join(',', (1..10));
print $numbers;

数组排序?

排序后,原始的数组不变(python比较智能,有两种排序函数)。

@chiefs = qw(li zhi xin);
print join(' ', sort @chiefs);

指定方法排序(硬方法 和 飞船运算符):

@numbers=(1,5,2,7,3,8,4);
@sorted=sort {return(1) if($a>$b);
return(0) if($a==$b);
return(-1) if($a<$b);
} @numbers;
print @sorted;

@numbers=(1,5,2,7,3,8,4);
@sorted=sort {$a <=> $b} @numbers; #a,b的顺序决定排序的类型
print @sorted;

字符串排序,需要使用cmp运算符,编写一个复杂的排序代码。

倒序操作?

分标量上下文(对标量里每个字符倒序) 和 列表上下文(对元素整体倒序)。

@lines = qw(li zhi xin);
print join(' ', reverse @lines);

 

第5学时 进行文件操作

perl的标量可以延长,存放足够长的一行内容;perl的数组可以扩展,可以存放文件的全部内容。

不在将输入和输出局限于键盘和终端,可以将输入和输出定向到指定文件

  • 打开和关闭文件
  • 将数据写入文件
  • 从文件读取数据
  • 健壮性

打开文件

文件句柄是对特定文件的一个引用(也是一种变量),包含了如何打开文件(文件位置)、位置信息(读到哪了)和读写属性(只读、覆盖、追加)。STDIN通常与键盘相连,从键盘输入信息。最好使用大写字母。

如果想打开文件,必须先创建一个句柄:open(filename, pathname),若打开失败,就会返回undef。

# 低级的打开和撤销策略
if (open(MYFILE, "mydatafile")){
    # 成功运行
}else{
    print "Cannot open mydatafile!\n";
    exit 1;
}

die函数可以停止函数的运行,利用了条件语句的执行特性

# 升级版打开或撤销
open(MYTEXT, "novel.txt") || die; 
close(MYTEXT);

默认是在当前文件夹查找文件,可以指定路径名。

# die函数升级版:$!系统需要的最后一个操作的出错消
open(MYFILE, "myfile") or die "Cannot open myfile: $!\n";

# 用warn取代die,程序不停止,只发出警告。
if (!open(MYFILE, "output")){
    warn "Cannot read output: $!\n";
}else{
    # 执行代码
}

 

读取文件

读取一行文本,完全类似于<STDIN>,默认该句柄已经打开。

# 读取一行文本  文件读完了<MYFILE>返回 undef
open(MYFILE, "myfile") or die "Can't open myfile: $!\n";
$line = <MYFILE>;

读取和输出整个文件

while(defined($a=<MYFLIE>)){  #defind()函数,检查表达式的值是否是undef
    print $a;
}

# 高级写法
while(<MYFILE>){
    print $_;
}

# 使用列表读取存储整个文件,只有在文件非常小时才这么做,非常耗内存。
open(MYFILE, "novel.txt") or die "$!";
@content = <MYFILE>;
close(MYFILE);

以下是语法在只读模式打开file.txt的。这里小于< signe 指示,文件必须以只读模式运行结束:

open(DATA, "<file.txt");
while(<DATA>){
   print "$_";
}

 

写入文件

想要写入文件,在打开文件句柄时就必须指定文件的打开方式(>, >>)。

# 写入并覆盖
open(NEWTH, ">output.txt") or die "Opening output.txt: $!";
# 写入并追加
open(APPFH, ">>logfile.txt") or "Opening logfile.txt: $!";

也可以用print( )将数据写入文件句柄

open(LOGF, ">>logfile") or die "$!";
if (! print LOGF "Time", scalar(localtime), "\n"){
    warn "Unable to write to the log file: $!";
}
close(LOGF);

自由文件句柄

perl启动时会默认打开三个文件句柄:STDOUTSTDINSTDERR,它们默认均与终端相连。

print函数默认是使用STDOUT

如何写入二进制的数据?

open(FH, "camel.gif") or die "$!";
binmode(FH);  # 标记为二进制文件
print FH "GIF87a\056\001\045\015\000";
close(FH);

文件测试(检查文件是否存在,权限)

-e  #文件存在,则真
-d  #是个目录,则真
-r  #文件可读,则真
-T  #文本文件,则真
-B  #二进制文件,则真

if (-s $filename){
    warn "$file contents will be overwritten!\n";
    warn "$file was last updated", -M $filename, "days ago.\n";
}

 

第6学时 模式匹配(perl的核心

识别输入数据流的模式(模式==正则表达式),需要对数据进行格式化,简单的split函数无法完成。

  • 创建简单的正则表达式
  • 正则表达式进行模式匹配
  • 正则表达式编辑字符串

什么是模式?

模式被括在模式匹配运算符中间,基本形式:m//;如:m/simon/。($_常常作为匹配的默认值)

print "yes\n" if(m/Piglet/);  # 如果使用的是斜杠//,那么m可以省略。

  • 除非是元字符,否则会严格匹配(可以用\屏蔽元字符)
  • 可以使用任意匹配的字符来替代斜杠(如m::)
  • 如果是斜杠,则可以省略前面的m
  • 变量也可以放在匹配模式里

元字符

# 圆点(.):匹配除了换行符外的任何单个字符,必须存在一个字符,但不能多于一个,仅且只能。
/p.t/  #可以匹配pot、pat,不能pt,不能paat;
#以下都是通配符(并非一对一)
# (+):使前面的字符与后面的字符最少匹配一次
/do+g/ #可以匹配dog、dooooog,不能dg;
# (*):进行0次或多次匹配,与(+)非常类似,但可以0次(注意:这和shell下的通配符意义完全不同)
/car*t/   #可以匹配cart、cat、carrrt;
# (?):前面的字符进行0次或一次匹配(不能超过一次),限定死了,0次或1次,只有两种可能
/c?ola/   #可以匹配cola、ola
# pat{n, m} # n:匹配的最小次数;m:匹配的最大次数
/x{5 

鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
上一篇:
Perl学习笔记(三)--列表与数组发布时间:2022-07-22
下一篇:
Perl面向对象编程的散列表实现和数组实现发布时间:2022-07-22
热门推荐
热门话题
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap