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

如何用Perl脚本递归匹配输入文件中的指定LaTeX数学命令数组元素

Perl脚本实现递归匹配嵌套LaTeX数学命令

嘿,我明白你需要处理那种包含多层嵌套LaTeX数学命令的文本文件,还要用Perl递归匹配指定的命令列表对吧?我给你写了一个实用的实现方案,每一步都加了注释,方便你理解和修改。

先理清楚需求

咱们要搞定的核心内容:

  • 输入文件是sample.txt,里面全是像\mathcal{\mathsf{HF交换算子}}、\mathbb{\mathbbm{ABC}}这种嵌套的LaTeX命令
  • 有一个命令数组@arr,包含boldsymbol、mathbb这些要匹配的命令
  • 必须递归匹配,不管这些命令嵌套了多少层

完整实现代码

直接上可运行的脚本,注释写得很清楚:

#!/usr/bin/perl
use strict;
use warnings;

# 定义输入文件路径
my $inp = "sample.txt";
# 定义需要匹配的LaTeX命令列表(你可以把省略的部分补充完整)
my @arr = qw(boldsymbol mathbb mathbbm mathbf mathit mathrm mathscr mathsf mathfrak mathcal);

# 把数组转换成正则的备选模式,用quotemeta避免特殊字符干扰
my $cmd_pattern = join('|', map { quotemeta($_) } @arr);
# 构建递归正则:匹配\命令{...},支持任意深度的嵌套
my $recursive_regex = qr/\\($cmd_pattern)\{(?:[^{}]+|(?R))*\}/;

# 一次性读取整个文件内容
open(my $fh, '<', $inp) or die "打不开文件 $inp: $!";
my $content = do { local $/; <$fh> };
close($fh);

# 全局查找所有匹配的嵌套命令
my @matches;
while ($content =~ /($recursive_regex)/g) {
    push @matches, $1;
}

# 输出匹配结果
print "找到的嵌套LaTeX命令:\n";
foreach my $match (@matches) {
    print "- $match\n";
}

# 如果需要替换命令或者做其他处理,在这里扩展就行
# 比如替换成自定义内容:
# $content =~ s/$recursive_regex/[$1]/g;

关键逻辑说明

  • 递归正则的核心:(?R)是Perl正则里的递归引用,它会重复使用整个正则表达式,这样就能完美匹配多层嵌套的\cmd{...}结构,不管套了多少层都能抓出来
  • 安全的模式构建:用quotemeta处理数组里的命令,防止命令里有正则特殊字符(虽然LaTeX命令一般没有,但这么做更稳妥)
  • 文件读取方式:local $/会把输入记录分隔符设为undef,这样就能一次性读取整个文件,避免逐行处理漏了跨行吗的命令

测试效果示例

假设sample.txt里的内容是:

测试内容:\mathcal{\mathsf{HF交换算子}},还有\mathbb{\mathbbm{ABC}},以及\mathbf{\mathit{加粗斜体文本}}

运行脚本后,输出会是:

找到的嵌套LaTeX命令:
- \mathcal{\mathsf{HF交换算子}}
- \mathbb{\mathbbm{ABC}}
- \mathbf{\mathit{加粗斜体文本}}
- \mathsf{HF交换算子}
- \mathbbm{ABC}
- \mathit{加粗斜体文本}

如果只想匹配最外层的命令,可以调整正则的捕获逻辑,比如把(?:[^{}]+|(?R))*改成(?:(?!\\($cmd_pattern)\{)[^{}])*|(?R),不过默认的全匹配模式应该能满足大部分需求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 07:46:33