基础
Hello World
#!/usr/bin/perl use strict; use warnings; print "Hello, World!\n"; say "Hello, World!"; # 需要 use feature 'say';
运行 Perl
perl script.pl # 执行文件 perl -e 'print "hi\n"' # 内联执行 perl -ne 'print' file # 逐行处理文件
注释与文档
# 单行注释 =pod 多行 POD 文档 =cut
变量
符印(Sigil)
$scalar标量(字符串、数字、引用)
@array有序列表
%hash键值对
$array[0]访问数组单个元素(标量上下文)
$hash{key}访问 hash 单个值(标量上下文)
标量变量
my $name = "Perl"; # 字符串 my $version = 5.40; # 数字 my $count = 42; # 整数 my $undef; # 未定义(undef) my $combined = "$name v$version"; # 插值
上下文
my @arr = (1, 2, 3); my $count = @arr; # 标量上下文:3 my @copy = @arr; # 列表上下文:(1, 2, 3) my $len = scalar @arr; # 强制标量上下文
特殊变量
$_默认变量(话题变量)
@_子程序参数
$!系统错误信息
$@eval 的错误
$0程序名
@ARGV命令行参数
%ENV环境变量
运算符
比较运算符
==, !=, <, >, <=, >=数值比较
eq, ne, lt, gt, le, ge字符串比较
<=>数值飞船运算符(返回 -1、0、1)
cmp字符串飞船运算符
=~正则匹配/绑定
!~正则否定匹配
字符串运算符
my $full = "Hello" . " " . "World"; # 拼接 my $line = "-" x 40; # 重复 my $len = length($full); # 11
逻辑运算符
&& / and逻辑与(低优先级:and
|| / or逻辑或(低优先级:or
// 已定义或(左侧已定义则返回左侧)
! / not逻辑非
? :三目运算符
控制流
条件语句
if ($x > 0) { print "positive\n"; } elsif ($x == 0) { print "zero\n"; } else { print "negative\n"; } print "yes\n" if $condition; # 后置 if print "no\n" unless $condition; # 后置 unless
循环
for my $i (0..9) { print "$i\n"; } foreach my $item (@array) { print "$item\n"; } while ($line = ) { chomp $line; } until ($done) { last if check(); }
循环控制
next跳到下一次迭代(类似 continue)
last退出循环(类似 break)
redo重新执行当前迭代
next LABEL跳到指定标签循环的下一次迭代
last LABEL退出指定标签循环
given / when
use feature 'switch'; given ($status) { when ("ok") { say "success"; } when ("error") { say "failed"; } default { say "unknown"; } }
子程序
基础子程序
sub greet { my ($name) = @_; return "Hello, $name!"; } my $msg = greet("Alice");
默认参数与命名参数
sub connect { my (%opts) = @_; my $host = $opts{host} // "localhost"; my $port = $opts{port} // 5432; return "$host:$port"; } connect(host => "db.example.com", port => 3306);
子程序引用
my $double = sub { return $_[0] * 2; }; print $double->(5); # 10 my @sorted = sort { $a <=> $b } @nums;
原型与签名
use feature 'signatures'; sub add($a, $b) { return $a + $b; } sub greet($name, $greeting = "Hello") { return "$greeting, $name!"; }
正则表达式
匹配
if ($str =~ /pattern/) { print "matched\n"; } if ($str =~ /(\d+)/) { print "number: $1\n"; } my @matches = ($str =~ /(\w+)/g); # 所有匹配
替换
$str =~ s/old/new/; # 替换首个匹配 $str =~ s/old/new/g; # 全局替换 $str =~ s/^\s+|\s+$//g; # 去除首尾空白 (my $clean = $str) =~ s/\W//g; # 非破坏性副本
修饰符
/i忽略大小写
/g全局(所有匹配)
/m多行(^$ 匹配行边界)
/s单行(. 匹配换行符)
/x扩展(允许空白和注释)
常用模式
\d, \D数字 / 非数字
\w, \W单词字符 / 非单词字符
\s, \S空白 / 非空白
\b单词边界
(?: ... )非捕获组
(?<name> ... )命名捕获(通过 $+{name} 访问)
文件 I/O
打开与读取
open(my $fh, '<', 'data.txt') or die "Cannot open: $!"; while (my $line = <$fh>) { chomp $line; print "$line\n"; } close($fh);
写入与追加
open(my $fh, '>', 'out.txt') or die "Cannot open: $!"; print $fh "Hello\n"; close($fh); open(my $fh, '>>', 'log.txt') or die "Cannot open: $!"; print $fh "entry\n"; close($fh);
一次性读取整个文件
use File::Slurp; my $content = read_file('data.txt'); my @lines = read_file('data.txt', chomp => 1);
文件测试
-e $path文件存在
-f $path是普通文件
-d $path是目录
-r / -w / -x可读 / 可写 / 可执行
-s $path文件大小(字节,空文件为 0)
-z $path文件大小为零
数组与 Hash
数组
my @arr = (1, 2, 3, 4, 5); push @arr, 6; # 追加 my $last = pop @arr; # 移除末尾 my $first = shift @arr; # 移除开头 unshift @arr, 0; # 在开头插入 my @slice = @arr[1..3]; # 切片
数组函数
scalar @arr元素数量
push / pop末尾添加/删除
shift / unshift开头删除/添加
splice(@a, 2, 1)删除索引 2 处的 1 个元素
sort @arr字母序排序
reverse @arr反转顺序
grep { /pat/ } @arr按模式过滤
map { $_ * 2 } @arr对每个元素进行变换
join(',', @arr)连接成字符串
Hash
my %user = (name => "Alice", age => 30); $user{email} = "a\@b.com"; # 添加键值对 delete $user{age}; # 删除键值对 my @keys = keys %user; my @vals = values %user;
遍历 Hash
while (my ($k, $v) = each %hash) { print "$k => $v\n"; } for my $key (sort keys %hash) { print "$key: $hash{$key}\n"; }
引用
创建引用
my $scalar_ref = \$name; my $array_ref = \@arr; my $hash_ref = \%hash; my $anon_arr = [1, 2, 3]; # 匿名数组引用 my $anon_hash = {a => 1, b => 2}; # 匿名 hash 引用
解引用
print $$scalar_ref; # 解引用标量 print $array_ref->[0]; # 箭头语法 print $hash_ref->{key}; # 箭头语法 my @copy = @$array_ref; # 解引用为数组 my %copy = %$hash_ref; # 解引用为 hash
复杂数据结构
my @users = ( { name => "Alice", age => 30 }, { name => "Bob", age => 25 }, ); print $users[0]->{name}; # "Alice"
ref() 函数
ref($r) eq 'SCALAR'标量引用
ref($r) eq 'ARRAY'数组引用
ref($r) eq 'HASH'hash 引用
ref($r) eq 'CODE'子程序引用
模块
使用模块
use strict; use warnings; use List::Util qw(sum max min); use File::Basename; use Cwd qw(abs_path);
创建模块
# MyModule.pm package MyModule; use Exporter 'import'; our @EXPORT_OK = qw(helper); sub helper { return "help"; } 1; # 模块必须返回真值
常用核心模块
List::Utilsum, max, min, reduce, any, all
File::Basenamebasename, dirname, fileparse
File::Pathmake_path, remove_tree
Getopt::Long命令行选项解析
JSONencode_json, decode_json
LWP::Simpleget($url) — 简易 HTTP 客户端
Data::Dumper数据结构调试输出
Carpcroak, confess — 更友好的错误信息
CPAN
cpan install Module::Name # 从 CPAN 安装 cpanm Module::Name # cpanminus(更快) perldoc Module::Name # 查阅模块文档