免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 6178 | 回复: 10
打印 上一主题 下一主题

将x^n全部替换为pow(x,n)函数的perl脚本 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2013-12-21 01:56 |只看该作者 |倒序浏览
5可用积分
不是很完美,求高手完美化:
  1. #!/usr/bin/perl

  2. # dynamic regexp
  3. my $levelN;
  4. $levelN = qr/ (?> [^()]+ | \( (??{ $levelN }) \) )* /x;

  5. # open file, do the replacement and print to screen.
  6. if(open(FH,@ARGV[0])){
  7.   while(){
  8.     my $line=$_;
  9.     my $line1=$line;
  10.     while(1){
  11.       $line1=~ s/(\($levelN\))\s*\^\s*(\($levelN\))/pow($1,$2)/g; #(a+b)^(c+d)
  12.       if("$line1" eq "$line"){last;}
  13.       $line=$line1;
  14.     }
  15.     while(1){
  16.       $line1=~ s/(\w*\.*\w*)\s*\^\s*(\($levelN\))/pow($1,$2)/g; #a^(b+c)
  17.       if("$line1" eq "$line"){last;}
  18.       $line=$line1;
  19.     }
  20.     while(1){
  21.       $line1=~ s/(\($levelN\))\s*\^\s*(\w*\.*\w*)/pow($1,$2)/g; #(a+b)^c
  22.       if("$line1" eq "$line"){last;}
  23.       $line=$line1;
  24.     }
  25.     while(1){
  26.       $line1=~ s/(\w*\.*\w*)\s*\^\s*(\w*\.*\w)/pow($1,$2)/g; #a^b
  27.       if("$line1" eq "$line"){last;}
  28.       $line=$line1;
  29.     }
  30.     print "$line1"
  31.   }
  32.   close(FH);
  33. }
  34. else{
  35.   print "Error: Open FILE '@ARGV[0]' fail!\n"
  36. }
复制代码

最佳答案

查看完整内容

{:2_169:}不完美,求高手完美化:old a = 1 ^ 2 ^ 3 * 2^3^4new a = pow(1, pow(2, 3)) * pow(2, pow(3, 4))old # There is no pownew # There is no powold b = 3 ^5 + 1 ^ 3 ^ 5 + 2 ^ 3new b = pow(3, 5) + pow(1, pow(3, 5) + pow(2, 3))old c = 1 ^(2+3)^2 + 1^(2^3+1)new c = pow(1, pow((2+3), 2) + pow(1, (pow(2, 3)+1)))

论坛徽章:
5
丑牛
日期:2014-01-21 08:26:26卯兔
日期:2014-03-11 06:37:43天秤座
日期:2014-03-25 08:52:52寅虎
日期:2014-04-19 11:39:48午马
日期:2014-08-06 03:56:58
2 [报告]
发表于 2013-12-21 01:56 |只看该作者
{:2_169:}不完美,求高手完美化:
  1. #!/usr/bin/perl -w

  2. while (<DATA>) {
  3.     print"old\t$_";
  4.     if (/\^/) {
  5.         $_ = scalar reverse $_;
  6.         1 while
  7.           s/(\).*?\((?:wop)?|\w+)\s*\^\s*(\).*?\((?:wop)?|\w+)/)$1 ,$2(wop/g;
  8.         print "new\t", scalar reverse $_;
  9.     }
  10.     else { print "new\t$_" }
  11.     print "\n";
  12. }
  13. __DATA__
  14. a = 1 ^ 2 ^ 3 * 2^3^4
  15. # There is no pow
  16. b = 3 ^5 + 1 ^ 3 ^ 5 + 2 ^ 3
  17. c = 1 ^(2+3)^2 + 1^(2^3+1)
复制代码
old     a = 1 ^ 2 ^ 3 * 2^3^4
new     a = pow(1, pow(2, 3)) * pow(2, pow(3, 4))

old     # There is no pow
new     # There is no pow

old     b = 3 ^5 + 1 ^ 3 ^ 5 + 2 ^ 3
new     b = pow(3, 5) + pow(1, pow(3, 5) + pow(2, 3))

old     c = 1 ^(2+3)^2 + 1^(2^3+1)
new     c = pow(1, pow((2+3), 2) + pow(1, (pow(2, 3)+1)))

论坛徽章:
0
3 [报告]
发表于 2013-12-21 10:08 |只看该作者
本帖最后由 climby 于 2013-12-21 15:31 编辑

我粗略写了个.非100%完美,因为应付你提到的几种case是没问题,但是如果原文件如果存在()未配对使用的情况,这个就有些问题了
注意正则中\w和\+中间的空格哦

  1. #!/usr/bin/perl

  2. my $file_name = $ARGV[0];

  3. open( my $fh, "<", $file_name ) or die "Can't open file:'$file_name'";
  4. while ( my $line = <$fh> ) {
  5.         if ( $line =~ m/\^/ ) {
  6.                 $line =~ s/(\(?[\w \+]+\)?)\^(\(?[\w \+]+\)?)/pow\($1,$2\)/g;

  7.         }
  8.                
  9.         print $line;
  10. }

复制代码

论坛徽章:
0
4 [报告]
发表于 2013-12-21 23:56 |只看该作者
是否考虑一下正则里的环视...

论坛徽章:
0
5 [报告]
发表于 2013-12-22 00:37 |只看该作者
回复 3# pitonas


    哈,之前没有考虑有人写a^b^c这样的情况哈。
   试了下,latex和matlab都是从左往右,mathematica里是从右到左。
   个人觉得还是按从左往右结合比较符合现代一般人的阅读习惯,而且容易处理。
   也就是a^b^c=(a^b)^c=a^(b*c),也就是pow(pow(a,b),c)或pow(a,b*c)。

论坛徽章:
0
6 [报告]
发表于 2013-12-22 00:39 |只看该作者
回复 4# perl6ide


    不好意思,菜鸟,不太懂环视的意思,还得再看看。

论坛徽章:
5
丑牛
日期:2014-01-21 08:26:26卯兔
日期:2014-03-11 06:37:43天秤座
日期:2014-03-25 08:52:52寅虎
日期:2014-04-19 11:39:48午马
日期:2014-08-06 03:56:58
7 [报告]
发表于 2013-12-22 17:55 |只看该作者
本帖最后由 pitonas 于 2013-12-22 10:57 编辑

{:2_172:} perl ** 是从右到左
回复 5# felonwan


   

论坛徽章:
0
8 [报告]
发表于 2013-12-22 18:50 |只看该作者
本帖最后由 felonwan 于 2013-12-22 19:15 编辑
pitonas 发表于 2013-12-22 17:55
perl ** 是从右到左
回复 5# felonwan


确实,Fortran也是右到左。

可以规避a^b^c这种模糊这种表达形式:加上判断,要求说明是(a^b)^c还是a^(b^c)。
if(/\^\s*\($levelN\)\s*\^/ | /\^\s*\w*\s*\^/)
  {die "Error: Form 'A^B^C' is not allowed, please clarify it as '(A^B)^C' or 'A^(B^C)'!";}

论坛徽章:
0
9 [报告]
发表于 2013-12-22 19:32 |只看该作者
本帖最后由 felonwan 于 2013-12-22 19:33 编辑
climby 发表于 2013-12-21 10:08
我粗略写了个.非100%完美,因为应付你提到的几种case是没问题,但是如果原文件如果存在()未配对使用的情况, ...


呵呵,不考虑原文件括号多了或少了、不成对,假设都是对的。
不好意思,我忘了给些测试用例了,像下面这样的得也能正确转化:

  c= (a+b*(a-b)) ^ (b-a) *a;
  d= ((a+b)^(c+a)) ^ (a+b^(c+b^a));
  printf("%lf\t%lf\t%lf\t%lf\t%lf\t%lf\t%lf\t%lf\n", 10^10.12^3.1, 10.11^11, a^2, a^n, (a+b)^2.2, (a+b)^(b-a), 2^(a+b), 2.0^(a+b));

论坛徽章:
0
10 [报告]
发表于 2013-12-22 21:40 |只看该作者
本帖最后由 felonwan 于 2013-12-23 10:00 编辑

综合climby和pitonas的代码写了一个,感觉挺不错了:功能完整,能想到的异常都能处理,代码简洁度也是非常好。
有一个小缺点:含有一些不必要的括号。
a^b^c是按(a^b)^c来处理的。
  1. #!/usr/bin/perl
  2. my $levelN = qr/ (?> [^()]+ | \( (??{ $levelN }) \) )* /x;
  3. while (<STDIN>) {
  4.   (/\^/) while
  5.     s/(\w*\.*\w+|[pow]*\($levelN\))\s*\^\s*([pow]*\($levelN\)|\w+\.*\w*)/pow($1,$2)/;
  6.   print "$_";
  7. }
复制代码
测试:
$ echo -e "a.b^(c+d)^(e-f/g^h*i)" | ./perfect
pow(pow(a.b,(c+d)),(e-f/pow(g,h)*i))
$ echo -e "^ (c+d) *^/ (e-f/g^h*i)" | ./perfect
^ (c+d) *^/ (e-f/pow(g,h)*i)

p.s. 完美真费时。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP