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

使用Perl脚本实现CSV词表匹配替换XML文件中中文短语为英文

我来帮你把这个Perl脚本补全,实现从CSV双语词表替换XML里中文短语为英文的功能~先给你梳理下核心要解决的问题,再给出完整的实现代码:

完善后的Perl脚本实现

我们需要搞定几个关键环节:

  • 正确读取CSV词表,构建中文到英文的映射关系
  • 安全处理XML内容替换(避免破坏XML的标签结构)
  • 统一编码,防止中文乱码

依赖模块说明

为了更稳妥地处理CSV和XML,建议安装两个CPAN模块(如果还没装的话):

  • Text::CSV:专门解析CSV文件,能处理包含逗号、引号的中文短语
  • XML::LibXML:安全解析修改XML,比直接正则替换更可靠,不会破坏标签结构

用cpanm安装的命令如下:

cpanm Text::CSV XML::LibXML

完整脚本代码

use Cwd;
use File::Basename;
use File::Copy;
use strict;
use warnings;
use Text::CSV;
use XML::LibXML;
use Encode qw(decode encode);

# 配置文件路径,替换成你实际的文件名
my $DIR = '/Users/moody/Desktop/chinese/';
my $csv_path = "$DIR/glossary.csv";
my $xml_path = "$DIR/source.xml";
my $xml_backup_path = "$xml_path.bak";

# 1. 读取CSV词表,构建中文→英文的映射哈希
my %glossary;
my $csv = Text::CSV->new({
    binary => 1,
    sep_char => ',',  # 如果你的CSV用制表符分隔,改成"\t"即可
    auto_diag => 1,   # 自动输出CSV解析错误,方便排查问题
}) or die "初始化CSV解析器失败: " . Text::CSV->error_diag();

open my $csv_fh, '<:encoding(UTF-8)', $csv_path or die "打不开CSV文件 $csv_path: $!";
# 如果CSV有表头,就跳过第一行;没有的话注释掉这行
$csv->getline($csv_fh);
while (my $row = $csv->getline($csv_fh)) {
    my ($chinese, $english) = @$row;
    # 去除短语前后的空白字符
    $chinese = trim($chinese);
    $english = trim($english);
    # 只添加有效条目
    $glossary{$chinese} = $english if $chinese && $english;
}
close $csv_fh;

# 2. 处理XML文件:替换中文短语为英文
# 先备份原文件,防止操作失误
copy($xml_path, $xml_backup_path) or die "备份XML文件失败: $!";

# 解析XML文档
my $parser = XML::LibXML->new({
    encoding => 'UTF-8',
    load_ext_dtd => 0,  # 不需要加载DTD的话可以关闭,提升速度
});
my $doc = $parser->parse_file($xml_path);

# 遍历所有文本节点,只替换文本内容,不碰标签
my $xpc = XML::LibXML::XPathContext->new($doc);
foreach my $text_node ($xpc->findnodes('//text()')) {
    my $content = $text_node->data;
    # 按短语长度从长到短替换,避免短短语先替换导致长短语匹配失败(比如先换"苹果"就会破坏"苹果手机"的匹配)
    foreach my $chinese (sort { length($b) <=> length($a) } keys %glossary) {
        $content =~ s/\Q$chinese\E/$glossary{$chinese}/g;
    }
    $text_node->setData($content);
}

# 保存修改后的XML文件,第二个参数1表示格式化输出,让XML更易读
$doc->toFile($xml_path, 1);

print "替换完成!原XML文件已备份为 $xml_backup_path\n";

# 辅助函数:去除字符串前后的空白
sub trim {
    my $str = shift;
    $str =~ s/^\s+|\s+$//g;
    return $str;
}

关键细节说明

  • CSV处理:用Text::CSV代替手动分割字符串,能兼容各种复杂的CSV格式(比如带引号的短语),同时指定UTF-8编码确保中文读取正确。
  • XML处理:用XML::LibXML只修改文本节点,完全不会破坏XML的标签结构,比直接正则替换整个XML文件安全得多。
  • 替换顺序:按短语长度从长到短排序替换,避免短短语提前替换破坏长短语的匹配。
  • 编码一致性:所有文件读写都指定UTF-8编码,彻底避免中文乱码问题。
  • 文件备份:修改前自动备份原文件,不怕操作失误丢失数据。

简化版(无需XML模块的场景)

如果你的XML结构非常简单,且中文短语都不在标签属性里,也可以用直接读写文件+正则替换的方式,代码更简洁:

use Cwd;
use File::Basename;
use File::Copy;
use strict;
use warnings;
use Text::CSV;
use Encode qw(decode encode);

my $DIR = '/Users/moody/Desktop/chinese/';
my $csv_path = "$DIR/glossary.csv";
my $xml_path = "$DIR/source.xml";
my $xml_backup_path = "$xml_path.bak";

# 读取CSV构建词表
my %glossary;
my $csv = Text::CSV->new({ binary => 1, sep_char => ',', auto_diag => 1 });
open my $csv_fh, '<:encoding(UTF-8)', $csv_path or die "打不开CSV文件: $!";
$csv->getline($csv_fh); # 跳过表头
while (my $row = $csv->getline($csv_fh)) {
    my ($cn, $en) = map { trim($_) } @$row;
    $glossary{$cn} = $en if $cn && $en;
}
close $csv_fh;

# 备份原文件
copy($xml_path, $xml_backup_path) or die "备份失败: $!";

# 读取XML内容并替换
open my $xml_fh, '<:encoding(UTF-8)', $xml_path or die "打不开XML文件: $!";
my $content = do { local $/; <$xml_fh> };
close $xml_fh;

# 按短语长度从长到短替换
foreach my $cn (sort { length($b) <=> length($a) } keys %glossary) {
    $content =~ s/\Q$cn\E/$glossary{$cn}/g;
}

# 写入修改后的内容
open my $xml_out_fh, '>:encoding(UTF-8)', $xml_path or die "写入XML失败: $!";
print $xml_out_fh $content;
close $xml_out_fh;

print "替换完成,原文件备份为 $xml_backup_path\n";

sub trim {
    my $s = shift;
    $s =~ s/^\s+|\s+$//g;
    return $s;
}

注意:这个简化版可能会误替换标签属性里的中文(如果有的话),所以优先推荐用XML解析模块的方式。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 04:21:48