正则表达式进阶 #
一、替换操作 #
1.1 基本替换 #
使用 s/// 进行替换:
perl
my $str = "Hello, World!";
$str =~ s/World/Perl/;
print $str;
1.2 全局替换 #
使用 g 修饰符替换所有匹配:
perl
my $str = "hello hello hello";
$str =~ s/hello/hi/g;
print $str;
1.3 忽略大小写 #
perl
my $str = "Hello HELLO hello";
$str =~ s/hello/hi/gi;
print $str;
1.4 使用捕获 #
perl
my $str = "Hello, World!";
$str =~ s/(\w+)/[$1]/g;
print $str;
1.5 交换位置 #
perl
my $str = "first last";
$str =~ s/(\w+) (\w+)/$2 $1/;
print $str;
二、替换修饰符 #
2.1 常用修饰符 #
| 修饰符 | 说明 |
|---|---|
| g | 全局替换 |
| i | 忽略大小写 |
| e | 执行代码 |
| r | 返回结果(不修改原字符串) |
2.2 执行代码 #
使用 e 修饰符执行代码:
perl
my $str = "1 2 3 4 5";
$str =~ s/(\d+)/$1 * 2/ge;
print $str;
2.3 返回结果 #
使用 r 修饰符返回新字符串:
perl
my $original = "Hello, World!";
my $modified = $original =~ s/World/Perl/r;
print "Original: $original\n";
print "Modified: $modified\n";
三、分割操作 #
3.1 基本分割 #
使用 split 按模式分割:
perl
my $str = "a,b,c,d";
my @arr = split /,/, $str;
print "@arr\n";
3.2 按空白分割 #
perl
my $str = "hello world\tperl\nprogramming";
my @words = split /\s+/, $str;
print "@words\n";
3.3 限制分割次数 #
perl
my $str = "a:b:c:d";
my @arr = split /:/, $str, 2;
print "@arr\n";
3.4 保留分隔符 #
perl
my $str = "hello123world456perl";
my @parts = split /(\d+)/, $str;
print "@parts\n";
四、高级模式 #
4.1 前瞻断言 #
| 断言 | 说明 |
|---|---|
| (?=…) | 正向前瞻 |
| (?!..) | 负向前瞻 |
perl
my $str = "hello123world456";
my @matches = $str =~ /\d+(?=world)/g;
print "@matches\n";
my @matches2 = $str =~ /\d+(?!world)/g;
print "@matches2\n";
4.2 后顾断言 #
| 断言 | 说明 |
|---|---|
| (?<=…) | 正向后顾 |
| (?<!..) | 负向后顾 |
perl
my $str = "price: $100, $200";
my @matches = $str =~ /(?<=\$)\d+/g;
print "@matches\n";
4.3 条件匹配 #
perl
my $str = "hello world";
if ($str =~ /(hello)(?(1) world)/) {
print "Matched\n";
}
4.4 嵌入代码 #
perl
my $str = "abc123def";
$str =~ s/(\d+)/length($1)/ge;
print $str;
五、引用模式 #
5.1 qr//创建正则对象 #
perl
my $pattern = qr/\d+/;
my $str = "abc123def";
if ($str =~ $pattern) {
print "Found digits\n";
}
5.2 组合模式 #
perl
my $word = qr/\w+/;
my $number = qr/\d+/;
my $str = "hello 123 world";
if ($str =~ /$word $number/) {
print "Matched\n";
}
5.3 动态模式 #
perl
my $search = "world";
my $pattern = qr/\b$search\b/i;
my $str = "Hello, World!";
if ($str =~ $pattern) {
print "Found\n";
}
六、实用示例 #
6.1 清理HTML标签 #
perl
my $html = "<p>Hello</p><div>World</div>";
$html =~ s/<[^>]+>//g;
print $html;
6.2 格式化电话号码 #
perl
my $phone = "1234567890";
$phone =~ s/(\d{3})(\d{3})(\d{4})/$1-$2-$3/;
print $phone;
6.3 提取链接 #
perl
my $html = '<a href="http://example.com">Link</a>';
if ($html =~ /href="([^"]+)"/) {
print "URL: $1\n";
}
6.4 CSV解析 #
perl
my $line = 'a,b,c,"d,e",f';
my @fields;
while ($line =~ /(?:^|,)("(?:[^"]*"")*[^"]*"|[^,]*)/g) {
my $field = $1;
$field =~ s/^"(.*)"$/$1/;
$field =~ s/""/"/g;
push @fields, $field;
}
print "@fields\n";
七、实践练习 #
练习1:文本清理 #
perl
#!/usr/bin/perl
use strict;
use warnings;
use v5.10;
my $text = " Hello, World! This is a test. ";
$text =~ s/^\s+//;
$text =~ s/\s+$//;
$text =~ s/\s+/ /g;
say "Cleaned: '$text'";
练习2:模板引擎 #
perl
#!/usr/bin/perl
use strict;
use warnings;
use v5.10;
my $template = "Hello, {{name}}! Your score is {{score}}.";
my %vars = (
name => "Tom",
score => 95,
);
my $result = $template;
$result =~ s/\{\{(\w+)\}\}/$vars{$1}/g;
say $result;
练习3:日志解析 #
perl
#!/usr/bin/perl
use strict;
use warnings;
use v5.10;
my $log = '192.168.1.1 - - [27/Mar/2024:10:00:00 +0000] "GET /index.html HTTP/1.1" 200 1234';
my $pattern = qr{
^
(\S+) # IP
\s+\S+\s+\S+ # ident and user
\s+\[([^\]]+)\] # timestamp
\s+"(\S+)\s+(\S+)" # method and path
\s+(\d+) # status
\s+(\d+) # size
}x;
if ($log =~ $pattern) {
say "IP: $1";
say "Time: $2";
say "Method: $3";
say "Path: $4";
say "Status: $5";
say "Size: $6";
}
八、总结 #
本章学习了:
- 替换操作 s///
- 分割操作 split
- 前瞻和后顾断言
- qr// 创建正则对象
- 实用正则技巧
下一章将学习面向对象编程。
最后更新:2026-03-27