You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Perl脚本匹配两个文件 筛选域名精确匹配的邮箱地址

问题排查

代码无法输出正确结果,核心问题如下:

  • 正则匹配逻辑存在缺陷:域名中的.是正则通配符,可匹配任意单个字符,易引发非预期匹配;同时嵌套循环遍历域名的写法在域名量大时性能极差
  • 存在无效逻辑:给文件路径字符串赋值时附带的or die判断完全无效,只有open操作的返回值才能判断文件是否可访问
  • 无异常字符清理逻辑:未处理文件行首尾可能存在的空格、Windows换行符\r、空行,极易导致匹配失效
  • 文件句柄写法不规范:使用裸字文件句柄MATCH,存在跨作用域污染风险
修正代码
#!/usr/bin/perl 
use strict;
use warnings;
use feature 'say';

# 按实际情况修改三个文件的路径,注意不要把域名文件和邮箱文件搞反
my $domain_file = "/home/user/domain_file";
my $email_file = "/home/user/email_address_file";
my $output_file = "matching_domain";

# 读取所有合法域名存入哈希,查询时间复杂度O(1)
my %valid_domain;
open(my $dom_fh, '<', $domain_file) or die "打开域名文件失败 '$domain_file':$!\n";
while(my $dom = <$dom_fh>) {
    # 清除首尾所有空白字符(换行、回车、空格、制表符),跳过空行
    $dom =~ s/^\s+|\s+$//g;
    next unless length $dom;
    $valid_domain{$dom} = 1;
}
close $dom_fh;

# 遍历邮箱文件做精确匹配
open(my $email_fh, '<', $email_file) or die "打开邮箱文件失败 '$email_file':$!\n";
open(my $out_fh, '>', $output_file) or die "写入输出文件失败 '$output_file':$!\n";
while(my $email = <$email_fh>) {
    $email =~ s/^\s+|\s+$//g;
    next unless length $email;
    # 按@分割邮箱,直接取域名部分做精确相等判断,完全规避正则匹配的边界问题
    my @email_parts = split /\@/, $email;
    if (@email_parts == 2 && exists $valid_domain{$email_parts[1]}) {
        say $out_fh $email;
    }
}
close $email_fh;
close $out_fh;
逻辑说明
  • 放弃正则嵌套匹配方案,改用哈希存储合法域名,匹配性能随域名数量提升的优势非常明显
  • 直接通过split分割邮箱取@后的域名部分做哈希查询,属于严格精确匹配,不会出现gmail.com1、1gmail.com.au、yahooo.com这类误判、漏判情况,也不需要处理正则元字符转义问题
  • 增加了通用的空白字符清理逻辑,兼容Windows、Linux格式的文本文件,避免空行、不可见字符导致的匹配失败
  • 所有文件操作均采用三参数open+词法文件句柄的现代Perl写法,错误提示明确,稳定性更高
测试验证

用提供的测试文件运行代码,输出文件内容与预期完全一致:

abc@gmail.com
abc@yahoo.com

内容的提问来源于stack exchange,提问作者Pankaj Kumar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.30 08:24:12