Regex 如何重构正则表达式匹配部分
例如,我在文本中简化了一些数学公式Regex 如何重构正则表达式匹配部分,regex,perl,Regex,Perl,例如,我在文本中简化了一些数学公式 This is ${\text{BaFe}}_{2}{\text{As}}_{2}$ crystal 我想把它转换成 This is BaFe2As2 crystal 也就是说,仅连接最内侧括号内的内容 我发现我可以使用正则表达式模式 \{[^\{\}]*\} 以匹配最里面的支架。但问题是如何将它们连接在一起 我不知道这是否可以用notepad++正则表达式替换。如果notepad++无法使用,我也可以接受perl一行程序解决方案。在notepad++中
This is ${\text{BaFe}}_{2}{\text{As}}_{2}$ crystal
我想把它转换成
This is BaFe2As2 crystal
也就是说,仅连接最内侧括号内的内容
我发现我可以使用正则表达式模式
\{[^\{\}]*\}
以匹配最里面的支架。但问题是如何将它们连接在一起
我不知道这是否可以用notepad++正则表达式替换。如果notepad++无法使用,我也可以接受perl一行程序解决方案。在notepad++中使用此正则表达式。我试着匹配最里面的花括号中不存在的所有内容,然后用空白字符串替换匹配内容
[^{}]*\{|\}[^{}]*
说明:
[^{}]*\{-匹配0+个既不是{也不是}后跟{
|-或
\}[^{}]*-matches}后跟0+个既不是{也不是}的字符
更换前:
更换后:
更新:
尝试此更新的正则表达式:
\$?(?=[^$]*\$[^$]*$)(?:[^{}]*{|}[^{}]*)(?=[^$]*\$[^$]*$)\$?
文档中两个$s之间的标记可能有多个这样的等式。因此,虽然需要在所有{}之间组合文本,但也需要将其约束在$pair内。然后所有这些方程都需要处理 在单个模式中匹配它会产生一个复杂的正则表达式。相反,我们可以首先提取一对$s中的所有内容,然后从中收集{}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等行
while条件中的正则表达式捕获两个$s之间的所有字符。循环体执行并再次检查条件后,正则表达式继续从上一个匹配的位置搜索字符串。这是由于全局in标量,由于它处于循环状态,所以强加在regex上。一旦不再有匹配项,循环终止
在体中,我们在{}之间进行匹配,同样由于/g,这是对方程中的所有{}进行的。然而,在这里,正则表达式位于列表上下文中,因为它被分配给一个数组,然后/g使它返回所有匹配项。它们被合并成一个字符串,并添加到数组中
为了替换已处理的方程式,请在替换中使用此选项
$text =~ s{ \$(.*?)\$ }{ join('', $1 =~ /\{([^{}]+)\}/g) }egx;
其中,修饰符e使替换部分作为Perl代码进行计算,并将结果用于替换匹配的部分。然后在其中,我们可以运行正则表达式来匹配所有{}的内容,并将其连接到字符串中,如上所述。我使用s{}{}分隔符和x修饰符,以便也能够在匹配部分中分隔事物
因为整个替换都有g修饰符,所以正则表达式会继续遍历$text,只要有方程要匹配,就用替换部分中计算的值替换它们
为了便于演示,我使用了从问题扩展而来的硬编码字符串。实际上,您将一个文件读入一个标量变量,然后对其进行处理
这取决于问题的前提,即等式中的感兴趣文本完全在{}之间
错过了寻找一个班轮的部分
perl -0777 -wnE'say join("", $1=~/\{([^{}]+)\}/g) while /\$(.*?)\$/g' file.tex
使用-0777,文件将被整个slurped读取,并且as-n在$变量中的输入行上提供一个循环;while条件中的正则表达式默认在$\上工作。在while的每次迭代中,捕获的等式的内容(单位为$1)直接匹配{}s
然后替换每个方程并打印出整个处理过的文件
perl -0777 -wne's{\$(.*?)\$}{join "", $1=~/\{([^{}]+)\}/g}eg; print' file.tex
在这里,我删除了连接上的多余空格和不必要的paren。我假设文档中有多个空格和不必要的paren。它们是否都是单个$s之间的内联方程式(如图所示),还是也有显示的方程式?@zdim它们都是内联方程式如果您可以使用Sublime,您可以试试吗?:\$?=[^$]+\$\G\A{?>{[^{}]+}{124;[^{}]+}?R*}\$?并替换为第一个捕获组$1相当不错!向上投票。然而,我发现你的方法与我的意图相反。实际上,我必须在文本中处理乳胶配方。例如,将这是${\text{BaFe}}{2}{\text{As}}}{2}$晶体更改为这是BaFe2As2晶体。这是我的错,我将更新我的帖子。@user15964我添加了一个更新,应该可以完成这项工作。非常感谢!您是否尝试过notepad++中的更新版本,它似乎与notepad++不兼容test@user15964转义花括号后,它也在记事本++中工作-\$??=[^$]*\$[^$]*$[^$]*$?:[^{}]*\{^}[^{}]*?=[^$]*\$[^$]*$\$[^$]*$\$?@user15964我使用了稍微扩展的字符串作为示例。让我知道演示如何将文件读入$text是否有用。这就是你实际要做的。@user15964我没有注意到你特别想要一条一行的。添加了。@user15964很明显,我也错过了你想要替换这些等式的机会,即使你清楚地说了!。添加到脚本版本和一行程序中。所以
谢谢你的解答和详尽的解释!作为一名perl初学者,您从您的答案中学到了很多:@user15964听到这个消息真的很高兴:如果有什么遗漏或不清楚,请告诉我,我将添加/编辑。