如何用Perl对LaTeX文件中{}内的带格式参考编号排序?
Perl 实现LaTeX文件中\refnumbers{}内编号的字母数字排序
需求描述
现有一个包含约10000条记录的LaTeX文件,每条记录由首词和逗号分隔的参考编号组成,部分编号带有\textbf{}、\page{}等LaTeX格式代码。需要对每条记录中\refnumbers{}大括号内的编号进行字母数字排序。
输入示例
ʾallik \refnumbers{9, 4306, 12, 9917, \textbf{28}, 8, 17, 13, 462, 3} ʾalmin \refnumbers{9, 4306, 12, \textbf{26}, 008, \page{17}, 13, 462, 3} ʾaran \refnumbers{282, \textbf{300-2}, 391, 829, 1021, 18, 361}
期望输出
ʾallik \refnumbers{3, 8, 9, 12, 13, \textbf{28}, 462, 4306, 9917} ʾalmin \refnumbers{3, 008, 9, 12, 13, \textbf{26}, 462, 4306, \page{17}} ʾaran \refnumbers{18, 282, \textbf{300-2}, 361, 391, 829, 1021}
解决方案
1. Perl 命令行版本
直接通过一行命令处理文件,适合快速执行:
perl -pe 's/\\refnumbers\{(.*?)\}/do { my @nums = split /,\s*/, $1; @nums = sort { my $a_val = $a =~ /(\d+(?:-\d+)?)/ ? $1 : $a; my $b_val = $b =~ /(\d+(?:-\d+)?)/ ? $1 : $b; $a_val <=> $b_val } @nums; "\\refnumbers{" . join(", ", @nums) . "}" }/ge' input.tex > output.tex
逻辑说明:
-pe:逐行读取输入文件,处理后输出结果- 正则匹配
\refnumbers{...}结构,提取大括号内的编号字符串 - 将编号按
,分割为数组,排序时提取每个编号的核心数字(含连字符格式如300-2),用数字比较规则排序 - 保留原LaTeX格式代码,仅调整编号顺序,最后重新拼接为
\refnumbers{...}格式
2. Perl 脚本版本
如果需要更易维护、可扩展的方案,可使用脚本:
创建sort_refnumbers.pl文件:
#!/usr/bin/perl use strict; use warnings; while (my $line = <>) { $line =~ s/\\refnumbers\{(.*?)\}/process_refs($1)/ge; print $line; } sub process_refs { my ($refs_str) = @_; my @refs = split /,\s*/, $refs_str; # 按编号核心数字排序,保留原格式 @refs = sort { my $a_num = $a =~ /(\d+(?:-\d+)?)/ ? $1 : $a; my $b_num = $b =~ /(\d+(?:-\d+)?)/ ? $1 : $b; $a_num <=> $b_num; } @refs; return "\\refnumbers{" . join(", ", @refs) . "}"; }
使用方式:
chmod +x sort_refnumbers.pl ./sort_refnumbers.pl input.tex > output.tex
优势:代码结构清晰,后续若需调整排序规则(如支持更多LaTeX格式),只需修改process_refs函数即可。
内容的提问来源于stack exchange,提问作者Robert E
相关产品推荐
相关产品推荐

