桂林市文章资讯

强大的Perl正则表达式实例详解

2026-04-21 12:38:02 浏览次数:0
详细信息

Perl 正则表达式实例详解

Perl 以其强大的正则表达式功能而闻名,被称为"正则表达式之王"。以下是一些实用的Perl正则表达式实例详解:

1. 基础匹配语法

# 基本匹配
my $string = "Hello World";
if ($string =~ /World/) {
    print "找到 'World'\n";
}

# 不区分大小写匹配
if ($string =~ /world/i) {
    print "不区分大小写匹配成功\n";
}

# 全局匹配
my $text = "cat bat sat fat";
while ($text =~ /(\w+at)/g) {
    print "找到: $1\n";
}

2. 元字符和字符类

# 字符类
my $str = "The price is $100.50";
if ($str =~ /[\$\d\.]+/) {
    print "找到货币金额\n";
}

# 否定字符类
if ($str =~ /[^0-9\.\$]+/) {
    print "找到非数字非货币符号\n";
}

# 预定义字符类
# \d 数字, \w 单词字符, \s 空白字符
# \D 非数字, \W 非单词字符, \S 非空白字符
my $data = "ID: A123, Date: 2023-12-01";
$data =~ /ID:\s*(\w+)/;
print "ID: $1\n";

3. 量词和分组

# 量词
my $text = "aaaabbbcccc";
if ($text =~ /a{2,4}/) {  # 匹配2到4个a
    print "找到2-4个连续的a\n";
}

# 非贪婪匹配
my $html = "<div>内容1</div><div>内容2</div>";
if ($html =~ /<div>(.*?)<\/div>/) {  # 使用?进行非贪婪匹配
    print "第一个div内容: $1\n";
}

# 分组捕获
my $email = "user@example.com";
if ($email =~ /^([\w\.-]+)@([\w\.-]+)\.([a-z]{2,})$/i) {
    print "用户名: $1\n";
    print "域名: $2\n";
    print "顶级域名: $3\n";
}

4. 零宽断言

# 正向预查
my $text = "perl python perlscript";
while ($text =~ /perl(?=\s|$)/g) {
    print "找到独立的perl\n";
}

# 负向预查
while ($text =~ /perl(?!script)/g) {
    print "找到不以script结尾的perl\n";
}

# 正向回顾
my $data = "100px 200em 300pt";
while ($data =~ /(?<=\d+)(px|pt)/g) {
    print "找到像素或点单位: $1\n";
}

5. 替换操作

# 基本替换
my $str = "Perl is great. Perl is powerful.";
$str =~ s/Perl/Python/;
print "$str\n";  # 只替换第一个

# 全局替换
$str = "Perl is great. Perl is powerful.";
$str =~ s/Perl/Python/g;
print "$str\n";  # 替换所有

# 使用回调函数替换
my $text = "价格: 100, 200, 300";
$text =~ s/(\d+)/$1 * 1.1/ge;
print "涨价10%后: $text\n";

# 大小写转换
my $mixed = "Hello World";
$mixed =~ s/(\w+)/\U$1\E/g;
print "大写: $mixed\n";

$mixed =~ s/(\w+)/\L$1\E/g;
print "小写: $mixed\n";

6. 复杂模式匹配

# IP地址匹配
my $ip = "192.168.1.1";
if ($ip =~ /^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/) {
    if ($1 <= 255 && $2 <= 255 && $3 <= 255 && $4 <= 255) {
        print "有效的IP地址\n";
    }
}

# URL解析
my $url = "https://www.example.com/path?query=value";
if ($url =~ m{^(https?)://([^/]+)(/.*)?$}) {
    print "协议: $1\n";
    print "主机: $2\n";
    print "路径: $3\n" if defined $3;
}

# CSV解析
my $csv = '"John","Doe",30,"New York"';
my @fields = $csv =~ /"([^"]*)"|([^,]+)/g;
print "字段: @fields\n";

7. 修饰符详解

# /i 忽略大小写
# /g 全局匹配
# /m 多行模式 (^和$匹配每行的开头结尾)
# /s 单行模式 (.匹配包括换行符)
# /x 忽略空白和注释

my $multiline = "第一行\n第二行\n第三行";
# 使用/m修饰符
while ($multiline =~ /^第(\w+)行$/mg) {
    print "行内容: $1\n";
}

# 使用/x修饰符编写可读的正则表达式
my $phone = "(123) 456-7890";
if ($phone =~ /
    ^\s*            # 开头可能有空白
    \(?             # 可选左括号
    (\d{3})         # 区号
    \)?             # 可选右括号
    [\s\-\.]*       # 分隔符
    (\d{3})         # 前缀
    [\s\-\.]*       # 分隔符
    (\d{4})         # 线路号
    \s*$            # 结尾可能有空白
/x) {
    print "区号: $1, 前缀: $2, 线路号: $3\n";
}

8. 实用函数

# split使用正则表达式
my $data = "John:Doe:30:New York";
my @fields = split /:/, $data;
print "姓名: $fields[0] $fields[1]\n";

# 更复杂的分隔符
my $log = "error|2023-12-01|main.c|10|Segmentation fault";
my @log_parts = split /\|/, $log;

# 使用捕获的分组
my $text = "key1=value1,key2=value2,key3=value3";
my %hash = $text =~ /(\w+)=(\w+)/g;
while (my ($k, $v) = each %hash) {
    print "$k => $v\n";
}

9. 高级技巧

# 命名捕获
my $date = "2023-12-01";
if ($date =~ /^(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})$/) {
    print "年: $+{year}, 月: $+{month}, 日: $+{day}\n";
}

# 条件表达式
my $test = "abc123";
if ($test =~ /^(?:(a)bc|(d)ef)(\d+)$/) {
    if (defined $1) {
        print "匹配abc模式\n";
    } elsif (defined $2) {
        print "匹配def模式\n";
    }
}

# 递归模式匹配(平衡括号)
my $nested = "a(b(c)d)e";
while ($nested =~ /\((?:[^()]|(?R))*\)/g) {
    print "找到括号内容: $&\n";
}

10. 性能优化建议

# 1. 使用编译后的正则表达式
my $regex = qr/\d{3}-\d{2}-\d{4}/;  # 社保号模式
my @matches = grep { /$regex/ } @data;

# 2. 避免回溯灾难
# 不好的写法: /.*a.*a.*a.*a.*/
# 好的写法: /[^a]*a[^a]*a[^a]*a[^a]*a/

# 3. 使用字符类代替可选字符
# 不好的写法: /cat|bat|rat|mat/
# 好的写法: /[cbrm]at/

# 4. 锚定正则表达式
# 尽量使用^和$明确边界

总结

Perl的正则表达式非常强大,支持:

掌握这些功能可以让你在文本处理、数据提取、格式验证等任务中游刃有余。记得根据具体需求选择最合适的正则表达式,并注意性能和可读性的平衡。

相关推荐