我很难弄清楚如何执行正则表达式替换来清理 LaTeX 文件中的一些文本。 LaTeX 文件看起来像
chapter{texorpdfstring{{II} {The Chapter
Title}}{II The Chapter Title}}
令人讨厌的是,这是一个多行章节声明,新行几乎可以出现在任何地方。 我不能使用常见的<>
习语来逐行读取文件并执行直接的正则表达式。
相反,我正在尝试这个:
#!/usr/bin/perl -i.old # In-place edit, backup as '.old'
use strict;
use warnings;
use Path::Tiny;
my $filename = shift or die "Usage: $0 FILENAME";
my $content = path($filename)->slurp_utf8;
$content =~ s|\chapter{.*{[IVXLCDM]*s*(.*)}}|\chapter{$1}|gms;
path($filename)->spew_utf8($content);
但是,正则表达式过于贪婪,在第一个chapter
声明开始匹配,在最后一个chapter
声明结束。 我想要的只是
- 删除
texorpdfstring
。 - 删除罗马数字
- 删除章节标题的多次出现
这样我的替代
chapter{texorpdfstring{{I} {The First
Chapter}}{I The First Chapter}}
It was the best of times.
chapter{texorpdfstring{{II} {The Second
Chapter}}{II The Second Chapter}}
It was the worst of times.
结果在
chapter{The First Chapter}
It was the best of times.
chapter{The Second Chapter}
It was the worst of times.
我现在能做什么?
编辑:我更改了演示文本。
如果我理解正确@zdim,他写下了替换而不转义大括号{},以便于验证。 很公平。 我尝试了@zdim的解决方案,但它输出:
chapter{The First
Chapter}
It was the worst of times.
如果您只能拥有显示的{...}
对
s/\chapter{\texorpdfstring{{ .*? }s*{ (.*?) }}s*{.*?}}/\chapter{$1}/gsx;
或
s/(\chapter){\texorpdfstring{{.*?}s*{(.*?)}}s*{.*?}}/${1}{$2}/gs;
其中语法需要${1}
(对于$1
),因为$1{...
将被解释为%1
的值。
或者,更确切地说
s/\chapterK{s*\texorpdfstring{{.*?}s*{(.*?)}}s*{.*?}}/{$1}/gs
其中K
形式的回溯会掉落以前的比赛。我仍然留{
重新输入可能更清晰的替换零件。
请在可能有空格的地方撒上s*
。
另请注意路径::微小::edit_utf8
path($filename)->edit_utf8( sub { s/.../.../gs } ); # regex as above
它将匿名子应用于 slurped 文件,而不是edit_lines
.
如果支撑表达式可以更自由地嵌套(例如使用{em ... }
等),则需要一种更系统的方法。 例如,请参阅文本::平衡并搜索"嵌套分隔符"。
一些正则表达式资源
Perl 文档
Perlretut,教程
Perlrequick,快速入门介绍
Perlre,语法的完整说明
perlreref,一个快速参考(其"另请参阅"部分本身很有用)
堆栈溢出
正则表达式信息 包含资源的入口门户
参考:这个正则表达式是什么意思? 包含 SO 帖子链接的庞大常见问题解答列表
学习正则表达式 最后包含一长串资源的概述
Regular-Expressions.info