regex - 如何重建正则表达式匹配部分

标签 regex perl

例如,我简化了文本中的一些 latex 数学公式

This is ${\text{BaFe}}_{2}{\text{As}}_{2}$ crystal

我想将其转换为

This is BaFe2As2 crystal

即仅连接最内括号内的内容。

我发现我可以使用正则表达式模式

\{[^\{\}]*\}

匹配最里面的括号。但问题是如何将它们连接在一起?

我不知道这是否可以在 Notepad++ 正则表达式替换中完成。如果notepad++没有能力,我也可以接受perl单行解决方案。

最佳答案

文档中显然可能存在多个这样的方程(两个 $ 之间的标记)。因此,虽然您需要在所有 {} 之间组装文本。 ,这也需要限制在$内一对。然后需要处理所有这些方程。

在单个模式中进行匹配会产生复杂的正则表达式。相反,我们可以首先提取一对 $ 中的所有内容。 s,然后收集 {} 内的文本由此而来,大大简化了正则表达式。这使得每个方程都经过两次,但出于计算目的,Latex 文档很小,并且效率损失无法被注意到。

use warnings;
use strict;
use feature 'say';

my $text = q(This is ${\text{BaFe}}_{2}{\text{As}}_{2}$ crystal,)
         . q( and ${\text{Some}}{\mathbf{More}}$ text);

my @results;

while ($text =~ /\$(.*?)\$/g) { 
    my $eq = $1; 
    push @results, join('', $eq =~ /\{([^{}]+)\}/g);
} 

say for @results;

这会打印行 BaFe2As2SomeMore .

while 中的正则表达式条件捕获两个 $ 之间的所有字符s。执行循环体并再次检查条件后,正则表达式继续从上一个匹配的位置搜索字符串。这是由于“全局”modifier /g 以标量 context ,强加于正则表达式,因为它处于循环条件中。一旦不再有匹配项,循环就会终止。

在正文中,我们匹配 {} ,又由于 /g这是为所有人完成的 {}等式中的 s。然而,这里的正则表达式位于列表上下文中(因为它被分配给一个数组),然后 /g使其返回所有匹配项。它们被连接成一个字符串,该字符串被添加到数组中。

为了替换处理后的方程,请在替换中使用它

$text =~ s{ \$(.*?)\$ }{ join('', $1 =~ /\{([^{}]+)\}/g) }egx;

其中修饰符 e使得替换部分被评估为 Perl 代码,并且其结果用于替换匹配的部分。然后在其中我们可以运行正则表达式来匹配所有 {} 的内容并将其连接到字符串中,如上所述。我用s{}{}分隔符和x修饰符,以便能够在匹配部分中留出空间。

由于整个替换有 g正则表达式不断修改 $text ,只要有匹配的方程,就用替换部分中计算的值替换它们。

我使用问题中的硬编码字符串(扩展)来进行简单的演示。实际上,您会将文件读入标量变量(“slurp”它)并对其进行处理。

这依赖于问题的前提,即方程中感兴趣的文本完全位于 {} 之间。 .


错过了寻找一句台词的部分

perl -0777 -wnE'say join("", $1=~/\{([^{}]+)\}/g) while /\$(.*?)\$/g' file.tex

-0777文件被整个读取(“slurped”),并且为 -n在输入行上提供循环,它位于 $_ 中多变的; while 中的正则表达式条件默认适用于 $_ 。在 while 的每次迭代中捕获方程的内容,在 $1 中, 直接匹配{} s。

然后替换每个方程并打印出整个处理后的文件

perl -0777 -wne's{\$(.*?)\$}{join "", $1=~/\{([^{}]+)\}/g}eg; print' file.tex

我在 join 上删除了多余的空格和(不必要的)括号.

关于regex - 如何重建正则表达式匹配部分,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53967131/

相关文章:

javascript - 如何在带有模式的文本中查找数字并在 JavaScript 中更改它

python 3 : Searching A Large Text File With REGEX

regex - 从区域文件中提取 IP 和指针记录

regex - 如何为以下情况创建正则表达式?

linux - 如何安装 Proc::Daemon 模块

javascript - 使用 JavaScript 验证电子邮件地址

linux - 调试 Linux 上的垃圾邮件脚本所在的位置

perl - 如何在不安装的情况下使用本地库中的模块?

linux - 如何在同一文件中添加行数

perl - 为什么Programming Perl 使用本地(不是我的)作为文件句柄?