Perl基本语法

这篇博客介绍了Perl编程的基础,包括注释、数据类型、判断语句(if/elsif/else, unless/else)、循环结构(while/until, for/foreach)以及控制循环的关键字。还讲解了Array和Hash的操作,如数组的push/pop/shift/unshift,Hash的赋值、遍历和检测。此外,还涉及文件I/O和Perl内置操作符,如算术和比较运算符。" 134440613,6970229,在Colab上运行图像生成算法,"['图像处理', '机器学习', 'Colab notebook', '开源工具', '深度学习']

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

注释

=pod
1.xxx
2.ddd
3.这是多行注释
=cut

# this is comment 单行注释

数据类型

# 标量
$a = "abcdefg";
$b = 123456;

# 数组
@array1 = (1, 2, 3, 4, 5);

# hash
%h = (
    "x" => 1,
    "y" => 2,
    "z" = 3,
);

判断语句

if … elsif … else

my @array = (1..10);
foreach (@array){
    if($_ == 1) {
        print "This is one($_)\n";
    }elsif($_ == 2) {
        print "This is two($_)\n";
    }elsif($_ == 3) {
        next;              # 跳到下一次 相当于其他语言中的continue
    }else {
        print "$_\n";
    }

    if($_ > 5){
        last;               # 跳出循环
    }
}

unless … else …

my $i = 1;
unless($i > 5){
    say "$i is not larger than 5";
}else {
    say "$i is larger than 5";
}

if和unless的区别:* if(condition) == unless(! condition) *

Perl 判断值为true或false的规则

  1. Perl 不是用的这些规则,但可以利用它们方便记忆,其结果是一致的。
  2. 如果值为数字,0 是 false;其余为真。
  3. 如果值为字符串,则空串(”)为 false;其余为真。
  4. 如果值的类型既不是数字又不是字符串,则将其转换为数字或字符串后再利用上述规则。
  5. undef为 false。所有的引用都是 true。

* 这些规则中有一个特殊的地方。 由于字符串 ‘0’ 和数字 0 有相同的标量值,Perl 将它们相同看待。也就是说字符串 ‘0’ 是唯一一个非空但值为0的串。 *

循环语句

while

$i = 1;
while($i < 10){
    print $i."\n";
    $i += 1;
}

while … continue…

#!/usr/bin/env perl

my $i = 1;
while($i < 5) {
    print "$i \n";
}continue {
    $i++;
}

until

my $i = 1;
until($i >=5 ) {
    print "$i \n";
    $i++;
}

while 和 until的区别: while(condition) == until(! condition)

do … while …

my @a = (1 .. 10);
my $i;
do {
    $i = shift @a;
    say $i;
} while ($i < 5);

Perl 中没有 do 。。。while。。。循环语句, 实际上这是do语句与while语句一起工作。

for

for($i=1; $i<=9; $i++){
    for($j=1; $j<=$i; $j++){
        print "$j*$i=".($i*$j)."\t";
    }
    print "\n";
}

foreach

@list = (1 .. 5);
foreach my $i(@list){
    print $i."\n";
}

foreach (@list){
    print "$_\n";
}

控制循环的三个关键字: next, last, and redo.

next 像C,java语言中的continue语句。跳过余下的代码块,进入循环中的下一个值。

while(<FILE>) {
    next if /^#/;   # 假如是空行,就读下一行。
    print "$_";
}

last像其他语言中的break语句。直接退出整个循环。

while(<FILE>) {
    last if /^End#/;  # 匹配End就 退出循环
    print "$_";
}

redo再一次执行本次循环

foreach(1 .. 5) {
    print "$_\n";
    chomp(my $ch=<STDIN>);
    if($ch =~ /a/) {
        redo;      # 当输入a是,再执行本次循环
    } 
}

举个例子

 foreach(1 .. 5) {
     print "Number:$_\n";
     print "input: last,next, redo, or none of them\n";
     chomp(my $ch=<STDIN>);
     last if($ch =~ /last/i);
     next if($ch =~ /next/i);
     redo if($ch =~ /redo/i);
     print "That wasn't any of the choices\n";
 }
 print "That's all\n";

运行结果:
Number:1
input: last,next, redo, or none of them
next
Number:2
input: last,next, redo, or none of them
abc
That wasn’t any of the choices
Number:3
input: last,next, redo, or none of them
redo
Number:3
input: last,next, redo, or none of them
redo
Number:3
input: last,next, redo, or none of them
last
That’s all


使用标签

在内部和外部的循环使用标签退出内部循环。

OUTER:
   while(<DATA>) {
      chomp;
      @linearray = split;
      foreach $word (@linearray) {
         next OUTER if($word =~ /next/i);
      }
   }

在循环过程中 $_ 为默认参数

foreach(1 .. 10) {
    print "$_\n";
}

Array

my @array = (1, 2, 3, 4, 5);
print $array[0];               # 打印第0个元素
print $array[1];               # 打印第1个元素
print $array[$#array];         # 打印最后一个元素

foreach my $i (@array) {       # 遍历整个Array
    print "$i\n";
}

数组赋值

$array[0] = “a”;               # 为地0个元素赋值

数组操作

push

往数组最末尾添加元素

my @temp;
push(@temp, 'a');
push(@temp, 'b');
push(@temp, 5);
push(@temp, 8);
print @temp;     # 输出 ab58
pop

从数组的末尾取得元素,并删除数组中该元素

my @temp = (1, 2, 3, 4, 5);
my $p1 = pop(@temp);   # $p1 = 5;
my $p2 = pop(@temp);   # $p2 = 4;
shift

从数组的最前头取得元素,并删除数组中该元素

my @temp = (1, 2, 3, 4, 5);
my $p1 = shift(@temp);   # $p1 = 1;
my $p2 = shift(@temp);   # $p2 = 2;
unshift

往数组最前头添加元素

my @temp = (1, 2, 3, 4, 5);
unshift(@temp, 'a');
unshift(@temp, 'b');
print @temp;         # 输出 ba12345;
分割数组
my @s1 = qw(a b c d e f);
my @s2 = splice(@s1, 2);
print @s1;      # ab
print @s2;      # cdef
qw 函数

qw(foo bar baz) 相当于 (‘foo’, ‘bar’, ‘baz’)
可以使用任何分隔符,而不仅仅是括号组。

my @a = qw(hello world I am here);
my @b = qw {
    /sbin
    /usr/sbin
    /usr/local/sbin
};

foreach(@a) {
    print "$_ \n";
}

Hash

第一种和第二种是一样的, 但第二种更直观。
第一种以(k1, v1, k2, v2, k3, v3)方式存在

my %h1 = ("dog", "1", "cat", "2", "fish", "3");
my %h2 = (
    "dog" => '1',
    "cat" => '2',
    "fish" => '3'
);
print $h1{'dog'};
print $h1{dog};

Hash赋值, 删除, 拷贝

$h1{'cow'} = '4';   #赋值
$h2{cow} = '4';     #赋值
delete( $h1{'dog'} );   #删除
%h3 = %h1;   #拷贝

Hash遍历

keys函数遍历Hash

keys 函数得到hash中所有key的数组
values 函数得到hash中所有的values的数组

my %h1 = (
    "dog" => '1',
    "cat" => '2',
    "fish" => '3'
);
my @animals = keys %h1;
foreach(@animals){
    print "$_ => $h{$_}\n";
}

my @numbers = values %h1;
foreach my $n(@numbers){
    print "$_\n";
}

可以用sort函数对key进行排序

foreach(sort keys %h1){
    print $_;
}
each函数遍历Hash
my %h1 = (
    "dog" => '1',
    "cat" => '2',
    "fish" => '3'
);
while(my($k, $v) = each(%h1)){
    print "$k => $v \n";
}

检测存在

exists函数来检测是否存在

my %h1 = (
    "dog" => '1',
    "cat" => '2',
    "fish" => '3'
);

if(exists($h1{"dog"})) {
    print "dog exist!"; 
}else {
    print "dot doesn't exist!";
}

哈希结构的2级哈希使用匿名散列引用

my $variables = {

   scalar  =>  { 
      description => "single item",
      sigil => '$',

     },
   array   =>  {
      description => "ordered list of items - www.yiibai.com",

      sigil => '@',
     },
   hash    =>  {

      description => "key/value pairs",
      sigil => '%',
     },

};

 print "$variables->{'scalar'}->{'sigil'}\n";

文件I/O

文件测试

选项含义
-r文件或目录对此(有效的)用户(effective user)或组是可读的
-w文件或目录对此(有效的)用户或组是可写的
-x文件或目录对此(有效的)用户或组是可执行的
-o文件或目录由本(有效的)用户所有
-R文件或目录对此用户(real user) 或组是可读的
-W文件或目录对此用户或组是可写的
-X文件或目录对此用户或组是可执行的
-O文件或目录由本用户所有
-e文件或目录名存在
-z文件存在,大小为 0(目录恒为 false)
-s文件或目录存在,大小大于 0(值为文件的大小,单位:字节)
-f为普通文本
-d为目录
-l为符号链接
-S为 socket
-p为管道(Entry is a named pipe(a “ fifo” ))
-b为 block (special 文件(如挂载磁盘))
-c为 character (special 文件(如 I/O 设备))
-usetuid 的文件或目录
-gsetgid 的文件或目录
-kFile or directory has the sticky bit set
-t文件句柄为 TTY( 系统函数 isatty() 的返回结果;不能对文件名使用这个测试)
-T文件有些像“文本”文件
-B文件有些像“二进制”文件
-M修改的时间(单位:天)
-A访问的时间(单位:天)
-C索引节点修改时间(单位:天)

举个列子

my $f = "/home/user/a.txt";
if(-e $f) {
    print "$f does exist!";
    if(-f $f) {
        print "$f is a file";
    }elsif(-d $d) {
        print "$f is a directory";
    }
}else {
    print "$f not found !";
}

Perl 内置操作符

算术运算符

操作符含义
+
-
*
/

数字比较运算符

操作符含义
==等于
!=不等于
<小于
>大于
<=小于等于
>=大于等于

字符串比较运算符

操作符含义
eqequality
neinequality
ltless than
gtgreater than
leless than or equal
gegreater than or equal

杂项运算符

操作符含义
.字符串连接 “abc” . “123”
x字符串多次连接 “abc” x 5
..范围 (1 .. 10)

Perl 内部变量

变量含义
$-当前页可打印的行数,属于Perl格式系统的一部分
$!根据上下文内容返回错误号或者错误串
$”列表分隔符
$#打印数字时默认的数字输出格式
$$Perl解释器的进程ID
$%当前输出通道的当前页号
$&与上个格式匹配的字符串
$(当前进程的组ID
$)当前进程的有效组ID
$*设置1表示处理多行格式.现在多以/s和/m修饰符取代之.
$,当前输出字段分隔符
$.上次阅读的文件的当前输入行号
$/当前输入记录分隔符,默认情况是新行
$:字符设置,此后的字符串将被分开,以填充连续的字段.
$;在仿真多维数组时使用的分隔符.
$?返回上一个外部命令的状态
$@Perl解释器从eval语句返回的错误消息
$[数组中第一个元素的索引号
$\当前输出记录的分隔符
$]Perl解释器的子版本号
$^当前通道最上面的页面输出格式名字
$^A打印前用于保存格式化数据的变量
$^D调试标志的值
$^E在非UNIX环境中的操作系统扩展错误信息
$^F最大的文件捆述符数值
$^H由编译器激活的语法检查状态
$^I内置控制编辑器的值
$^L发送到输出通道的走纸换页符
$^M备用内存池的大小
$^O操作系统名
$^P指定当前调试值的内部变量
$^R正则表达式块的上次求值结果
$^S当前解释器状态
$^T从新世纪开始算起,脚步本以秒计算的开始运行的时间
$^W警告开关的当前值
$^XPerl二进制可执行代码的名字
$_默认的输入/输出和格式匹配空间
$|控制对当前选择的输出文件句柄的缓冲
$~当前报告格式的名字
$`在上个格式匹配信息前的字符串
$’在上个格式匹配信息后的字符串
$+与上个正则表达式搜索格式匹配的最后一个括号
$<当前执行解释器的用户的真实ID
$< digits >含有与上个匹配正则表达式对应括号结果
$=当前页面可打印行的数目
$>当前进程的有效用户ID

包含正在执行的脚本的文件名

变量含义
$ARGV从默认的文件句柄中读取时的当前文件名
%ENV环境变量列表
%INC通过do或require包含的文件列表
%SIG信号列表及其处理方式
@_传给子程序的参数列表
@ARGV传给脚本的命令行参数列表
@INC在导入模块时需要搜索的目录列表
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值