Perl 特殊变量
输入输出特殊变量
$_ - 默认输入和模式搜索变量
perl
# 在循环中使用默认变量
foreach (1..5) {
print; # 打印 $_
}
# 在模式匹配中使用
$_ = "Hello World";
print if /World/; # 如果包含 World 则打印
# 在 grep 和 map 中使用
my @evens = grep { $_ % 2 == 0 } (1..10);
my @squared = map { $_ * $_ } (1..5);@_ - 子程序参数数组
perl
sub add {
my ($a, $b) = @_;
return $a + $b;
}
print add(10, 20); # 30$. - 当前行号
perl
while (my $line = <STDIN>) {
print "Line $.: $line";
}$/ - 输入记录分隔符
perl
# 读取整个文件
local $/;
my $content = <FILE>;
# 段落模式(空行分隔)
$/ = "";
my @paragraphs = <FILE>;
# 自定义分隔符
$/ = "---\n";
my @records = <FILE>;$\ - 输出记录分隔符
perl
local $\ = "\n"; # 每次打印后自动添加换行符
print "Hello"; # 输出:Hello\n
print "World"; # 输出:World\n$| - 自动刷新
perl
$| = 1; # 启用自动刷新
print "Processing..."; # 立即输出
sleep(2);
print "Done\n";$" - 列表内插分隔符
perl
$" = ", ";
my @array = (1, 2, 3);
print "@array"; # 输出:1, 2, 3$, - 输出字段分隔符
perl
$, = " - ";
print "a", "b", "c"; # 输出:a - b - c模式匹配特殊变量
$1, $2, $3, ... - 捕获组
perl
if ("hello world" =~ /(hello) (\w+)/) {
print "$1\n"; # hello
print "$2\n"; # world
}
if ("2024-01-15" =~ /(\d{4})-(\d{2})-(\d{2})/) {
print "Year: $1, Month: $2, Day: $3\n";
}$& - 匹配的字符串
perl
if ("hello world" =~ /world/) {
print "Matched: $&\n"; # world
}`$`` - 匹配前的字符串
perl
if ("hello world" =~ /world/) {
print "Before: $`\n"; # hello
}$' - 匹配后的字符串
perl
if ("hello world" =~ /world/) {
print "After: $'\n"; # 空
}
if ("hello world test" =~ /world/) {
print "After: $'\n"; # test
}$+ - 最后一个捕获组
perl
if ("test@example.com" =~ /(\w+)@(\w+)\.(.+)/) {
print "Last capture: $+\n"; # com
}$^N - 最近完成的捕获组
perl
if ("test123" =~ /(test)(\d+)/) {
print "Most recent: $^N\n"; # 123
}进程特殊变量
$$ - 当前进程 ID
perl
print "PID: $$\n";$? - 最后一个子进程的退出状态
perl
system("ls -l");
if ($? != 0) {
print "Command failed with status: $?\n";
}
# 获取退出码和信号
my $exit_status = $? >> 8;
my $signal = $? & 127;$0 - 程序名
perl
print "Program name: $0\n";$^O - 操作系统名
perl
print "OS: $^O\n"; # linux, darwin, MSWin32 等$^T - 脚本开始时间
perl
my $start_time = $^T;
print "Start time: ", scalar localtime($start_time), "\n";
# 计算运行时间
my $elapsed = time - $^T;
print "Elapsed: $elapsed seconds\n";$^X - Perl 解释器路径
perl
print "Perl interpreter: $^X\n";文件句柄特殊变量
ARGV - 命令行参数
perl
# 读取命令行指定的文件
while (<>) {
print;
}
# 访问当前文件名
print "Current file: $ARGV\n";@ARGV - 命令行参数数组
perl
foreach my $arg (@ARGV) {
print "Argument: $arg\n";
}STDIN, STDOUT, STDERR
perl
# 标准输入
my $input = <STDIN>;
# 标准输出
print STDOUT "Output to STDOUT\n";
# 标准错误
print STDERR "Error message\n";格式化特殊变量
$# - 数组最后一个索引
perl
my @array = (10, 20, 30);
print "Last index: $#array\n"; # 2
print "Array size: " . ($#array + 1) . "\n"; # 3$% - 当前页号
perl
# 在格式化输出中使用
format STDOUT_TOP =
Page @<
$%
.$= - 每页行数
perl
$= = 50; # 设置每页 50 行$- - 当前行数
perl
print "Lines left on this page: $-\n";$~ - 当前格式名
perl
$~ = "MYFORMAT";
format MYFORMAT =
@<<<<<<<<<< @<<<<<<<<< @>>>>>>>
$name, $email, $salary
.正则表达式特殊变量
$^R - 最后成功的正则表达式代码执行结果
perl
if ("test123" =~ /(?{$count++})test/) {
print "Code executed $^R times\n";
}其他重要特殊变量
$! - 系统错误消息
perl
open(my $fh, '<', 'nonexistent.txt')
or die "Error: $!";$@ - eval 错误消息
perl
eval {
die "An error occurred";
};
if ($@) {
print "Error: $@\n";
}$^E - 扩展错误消息
perl
open(my $fh, '<', 'file.txt') or die "Error: $!, $^E";$^I - 原地编辑备份扩展名
perl
local $^I = '.bak'; # 创建备份文件
while (<>) {
s/foo/bar/g; # 替换 foo 为 bar
print; # 输出修改后的内容
}
# 运行:perl -i.bak script.pl file1.txt file2.txt$^F - 系统文件描述符最大值
perl
print "Max file descriptors: $^F\n";$^H - 语法哈希(内部使用)
perl
# 用于修改编译器行为$^M - 紧急内存池
perl
# 用于内存不足时的紧急分配
$^M = ' ' x 1024 * 1024;$^P - 调试器标志
perl
$^P = 0x01; # 启用单步调试$^S - 当前解释器状态
perl
eval {
print "In eval: $^S\n"; # 1
};
print "Not in eval: $^S\n"; # 0$^V - Perl 版本
perl
my $version = $^V;
printf "Perl version: v%d.%d.%d\n",
$version->[0], $version->[1], $version->[2];实践示例
示例 1:行号和文件处理
perl
#!/usr/bin/perl
use strict;
use warnings;
my $file = shift or die "Usage: $0 <filename>";
open(my $fh, '<', $file) or die "Cannot open $file: $!";
my $line_count = 0;
while (my $line = <$fh>) {
chomp $line;
$line_count++;
printf "%4d: %s\n", $., $line;
}
close($fh);
print "\nTotal lines: $line_count\n";示例 2:正则表达式提取
perl
#!/usr/bin/perl
use strict;
use warnings;
my $text = "Contact us at support@example.com or sales@example.com";
while ($text =~ /(\w+)@(\w+)\.(\w+)/g) {
print "Email: $&\n";
print "Username: $1\n";
print "Domain: $2\n";
print "TLD: $3\n";
print "Context: $` <<MATCH>> $'\n";
print "-" x 40 . "\n";
}示例 3:命令行工具
perl
#!/usr/bin/perl
use strict;
use warnings;
print "Script name: $0\n";
print "Arguments:\n";
foreach my $i (0..$#ARGV) {
print " [$i] $ARGV[$i]\n";
}
print "\nTotal arguments: " . scalar(@ARGV) . "\n";
print "Perl version: $^V\n";
print "OS: $^O\n";
print "PID: $$\n";
# 读取命令行指定的文件
if (@ARGV) {
print "\nProcessing files:\n";
while (<>) {
print "File $ARGV, Line $.: $_";
}
}示例 4:进度显示
perl
#!/usr/bin/perl
use strict;
use warnings;
use Time::HiRes qw(sleep);
$| = 1; # 启用自动刷新
my @files = ('file1.txt', 'file2.txt', 'file3.txt', 'file4.txt', 'file5.txt');
my $total = scalar(@files);
print "Processing $total files...\n";
for my $i (0..$#files) {
my $progress = ($i + 1) / $total * 100;
printf "\rProgress: [%-50s] %.0f%% (%d/%d)",
"=" x ($progress / 2),
$progress,
$i + 1,
$total;
sleep 0.5; # 模拟处理
}
print "\nDone!\n";小结
本章节学习了 Perl 的特殊变量:
- ✅ 输入输出特殊变量
- ✅ 模式匹配特殊变量
- ✅ 进程特殊变量
- ✅ 文件句柄特殊变量
- ✅ 格式化特殊变量
- ✅ 其他重要特殊变量
接下来,我们将学习 Perl 正则表达式。