Perl 正则表达式,用于提取多行 LaTeX 章节名称



我很难弄清楚如何执行正则表达式替换来清理 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声明结束。 我想要的只是

  1. 删除texorpdfstring
  2. 删除罗马数字
  3. 删除章节标题的多次出现

这样我的替代

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

最新更新