【问题标题】:sed: Nested pattern replacementsed:嵌套模式替换
【发布时间】:2021-07-16 17:26:39
【问题描述】:

我有一堆 C 代码,涉及到以下形式的幂函数调用:

Power(x,2)

我想扩展它,以便明确写出所有权力,例如Power(x,2) 应替换为(x)*(x)。 我目前正在使用以下sed 命令:

sed -e 's/Power(\([^,]*\),2)/(\1)*(\1)/g' main.c

这适用于Power(x,2)Power(x+y-3*z,2) 等简单情况。 但是,一旦我对函数进行了嵌套调用,它就不再起作用了。我希望它从函数的最里面的实例开始并向外工作。例如,如果输入是

Power(Power(x,2) + x,2)

预期的输出是

((x)*(x) + x)*((x)*(x) + x)

但是使用上面的表达式,它会返回

(Power(x)*(Power(x) + x,2)

有没有简单优雅的方法来解决这个问题?

【问题讨论】:

  • sed 中有一种方法,前提是您不要将Power 用于 2 以外的幂。(sed 不适用于数字。)我不知道我会打电话很简单。
  • 你介意告诉我路吗?如果它不简单,那也不算太糟糕,只要它有效。
  • 我认为这可以通过告诉 sed 从输入的右端开始并向左工作来解决。这样,它将首先击中最里面的 Power() 并打开它,然后才击中外面的那个。有没有办法做到这一点?
  • perl -pe 'while(s/Power\(((?:(?!Power\().)+?),2\)/($1)*($1)/){}' 适用于您给定的样本,但我认为不适用于所有情况。

标签: regex sed nested


【解决方案1】:

基于给定的样本:

$ cat ip.txt
Power(Power(x,2) + x,2)
Power(x+y-3*z,2)
Power(x + Power(x,2),2)

$ perl -pe 'while(s/Power\(((?:(?!Power\().)+?),2\)/($1)*($1)/){}' ip.txt
((x)*(x) + x)*((x)*(x) + x)
(x+y-3*z)*(x+y-3*z)
(x + (x)*(x))*(x + (x)*(x))
  • 只要替换成功,while 循环就会起作用
  • (?:(?!Power\().)+? 只要不是Power(,这将与Power( 之后的文本最小匹配
    • 非贪婪量词需要在,2 第一次出现时停止
    • (?:(?!REGEXP).)+ 是匹配文本的一般方法,只要给定的 REGEXP 不匹配,类似于[^set]+ 匹配给定集合以外的字符

对于通用权力(而不是 2 的特定情况):

$ cat ip.txt
Power(Power(x,2),3)
Power(Power(x,3),2)

$ perl -pe 'while(s/Power\(((?:(?!Power\().)+?),(\d+)\)/"($1)" . "*($1)" x ($2-1)/e){}' ip.txt
((x)*(x))*((x)*(x))*((x)*(x))
((x)*(x)*(x))*((x)*(x)*(x))
  • (\d+)捕获功率值
  • "($1)" . "*($1)" x ($2-1) 使用字符串连接运算符. 和字符串重复运算符x 和捕获的功率值构建扩展版本
  • e 允许在替换部分中使用 Perl 代码的标志

【讨论】:

  • 你好 Sundeep,我希望你还在阅读这篇文章。虽然这个解决方案适用于我在原帖中提到的问题,但当我使用不同参数嵌套权力时它会失败。更具体地说,我有一个类似 Power(Power(x,2),3) 的表达式,我首先使用命令perl -pe while(s/Power\(((?:(?!Power\().)+?),2\)/($1)*($1)/){}' file.txt,然后使用perl -pe while(s/Power\(((?:(?!Power\().)+?),3\)/($1)*($1)*($1)/){}' file.txt,它工作正常。但是当Powers的顺序交换时,即Power(Power(x,3),2)输出错误:Power((x,3))*(x,3)) 你知道解决办法吗?
  • perl -pe 'while(s/Power\(((?:(?!Power\().)+?),(\d+)\)/"($1)" . "*($1)" x ($2-1)/e){}'怎么样
猜你喜欢
  • 2018-01-16
  • 1970-01-01
  • 1970-01-01
  • 2021-07-20
  • 2016-06-17
  • 2011-08-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多