例如,我简化了文本中的一些 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;
这会打印行 BaFe2As2
和SomeMore
.
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/