正则表达式进阶 #

一、替换操作 #

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