perl - 如何使用 AWK 或 sed 或 Perl 进行此类替换?

标签 perl bash shell sed awk

想要使用以下替换规则将乘法符号“*”替换为“tensor”,将幂符号“^”替换为“p_tensor”:

    a(k)^n --> p_tensor(n,a(k))
    a(i)*a(j) --> tensor(a(i),a(j)), when i=/=j

但是当符号“*”在数字和a(i)之间时,比如3*a(i),我们应该保持符号“*”的原样。

例如,

    5*a(i)*a(j)*(a(k1)+3*a(k2)) --> 5*tensor(tensor(a(i),a(j)),a(k1)+3*a(k2))
    a(i)^2*a(j)^2  --> tensor(p_tensor(2,a(i)),p_tensor(2,a(j)))
    ...

现在我想使用 AWK 或 sed 或 Perl 重新格式化以下表达式:

    3*a(3)^2+6*a(1)^2*(5*a(2)^2-2*a(4))+6*a(2)*a(4)+6*a(1)*(-4*a(2)*a(3)+a(5))

有什么想法吗?

替换后的预期结果应该是

    3*p_tensor(2,a(3))+6*tensor(p_tensor(2,a(1)),(5*p_tensor(2,a(2))-2*a(4))+6*tensor(a(2),a(4))+6*tensor(a(1),(-4*tensor(a(2),a(3))+a(5))

最佳答案

正则表达式不能做任意嵌套,也不能做优先级和结合性。为此需要解析器;但是,您可以从这里开始:

Perl:

while(<>) {
   s/(a\(\d+\))\^(\d+)/p_tensor($2,$1)/g;
   s/(a\((\d+)\))\*(a\((\d+)\))/tensor($1, $3)/g if $2 != $4;
   print;
}

这很接近,并且让您达到一个级别。然后可以通过添加额外的递归定义的模式来“伪造”额外的嵌套,这些模式可以达到您需要的任何最大嵌套深度(通常不多......表达式在实践中很少有 3-4 层深度,这可能适合您)。

试试看:

echo "3*a(3)^2+6*a(1)^2*(5*a(2)^2-2*a(4))+6*a(2)*a(4)+6*a(1)*(-4*a(2)*a(3)+a(5))" | perl t.pl

或类似的东西。

关于perl - 如何使用 AWK 或 sed 或 Perl 进行此类替换?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13853117/

相关文章:

perl - 我对 Perl 自动生成示例的分析

css - Perl Mojo::DOM 修改属性值

linux - Bash 脚本中 FTP 将文件复制到远程计算机失败

linux - shell 脚本 (AIX) : Extracting OS and browser information from user agent string

regex - 为什么我的 Perl 正则表达式删除了 .在文件扩展名之前?

Perl Term::ReadLine::Gnu 信号处理难点

bash - 在 bash 命令行中将十六进制字符串转换为 ascii

linux - 尝试在 bash 中更改文件名

shell - 提取两个字符串之间的文本。这些字符串有空格,保存在变量中

linux - 在Linux命令行上将文件移动到匹配的文件夹中