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

标签 regex 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/\\chapter\K{\s*\\texorpdfstring{{.*?}\s*{(.*?)}}\s*{.*?}}/{$1}/gs

其中\K form of lookbehind放弃之前的比赛。我仍然留下 { 重新输入以获得可能更清晰的替换部分。

请在可能有空格的地方添加 \s*

另请注意 Path::Tiny::edit_utf8

path($filename)->edit_utf8( sub { s/.../.../gs } );  # regex as above

它将匿名子应用到slurped文件,而不是edit_lines

如果花括号表达式可以更自由地嵌套(比如使用 {\em ... } 等),则需要一种更加系统的方法。例如,参见Text::Balanced并搜索“嵌套分隔符”。


一些正则表达式资源

Perl 文档

堆栈溢出

Regular-Expressions.info

关于regex - 用于提取多行 LaTeX 章节名称的 Perl 正则表达式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48509953/

相关文章:

python - 使用正则表达式将文本文件拆分为多个新文件

python - 替换用小写字母括起来的字符

java - 在 Linux 上将 MSword 转换为 XML/HTML

latex - TeX:字符串解析和空格剥离

python - 如何自动替换多个文件文本内容中的一个字符?

regex - 如何 grep 向量并返回单个 TRUE 或 FALSE?

c# - 名称的正则表达式应以字母开头

Perl 循环不工作

perl - 如何使用GetOpt传递文件

LaTex,Beamer 和 Listings 的问题