免费注册 查看新帖 |

Chinaunix

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

[文本处理] 将^全部替换为pow(x,n)函数 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2013-12-20 13:44 |只看该作者 |倒序浏览
假如是c语言里的pow(x,n)函数是全部用a^b这样的形式写的,怎么把它们替换回来?
只用cut、grep、sed、awk 等这样的脚本能否处理?
好像涉及到嵌套的括号匹配哈。

例如,如下文本:
c= b /(a-b) *(a+b*(a-b)) ^ (b-a) *a;
printf("%lf\t%lf\t%lf\t%lf\n",10 ^ 10,10.11 ^ 11, a ^ 2,a ^ n,(a+b) ^ 2, (a+b) ^ (b-a),2 ^ (a+b), 2.0 ^ (a+b));

论坛徽章:
0
2 [报告]
发表于 2013-12-20 13:55 |只看该作者
自己写的不对的脚本,抛砖引玉。

#!/bin/bash

fnw=`basename $1`_n.c
cp $1 $fnw

#简单的能用
# a.b ^ c
sed -i 's/\([a-zA-Z0-9]\{1,\}\)\.\([a-zA-Z0-9]\{1,\}\)\([ ]\{0,\}\)\^\([ ]\{0,\}\)\([a-zA-Z0-9]\{1,\}\)/pow(\1.\2,\3)/g' $fnw
# a ^ b
sed -i 's/\([a-zA-Z0-9]\{1,\}\)\([ ]\{0,\}\)\^\([ ]\{0,\}\)\([a-zA-Z0-9]\{1,\}\)/pow(\1,\4)/g' $fnw

#下面的都有问题,不能处理括号的配对
# (a+b)^n
sed -i 's/\([^a-zA-Z0-9]\{0,\}\)\((.*)\)\([\ ]\{0,\}\)\^\([ ]\{0,\}\)\([a-ZA-Z0-9]\)\([^a-zA-Z0-9]\{0,\}\)/\1pow(\2,\5)\6/g' $fnw
# a^(c+d)
sed -i 's/\([^a-zA-Z0-9]\{0,\}\)\([a-zA-Z0-9]\)\([\ ]\{0,\}\)\^\([ ]\{0,\}\)\((.*)\)\([^a-zA-Z0-9]\{0,\}\)/pow(\1,\4)\5/g' $fnw
# (a+b)^(c+d)
sed -i 's/\([,=+\-\*\/\^\&\|]\{1,\}\)\([ ]\{0,\}\)\((.*)\)\([ ]\{0,\}\)\^\([ ]\{0,\}\)\((.*)\)\([ ]\{0,\}\)\([,+\-\*\/\^\&\|]\{0,\}\)/\1pow(\3,\6)/g' $fnw

论坛徽章:
0
3 [报告]
发表于 2013-12-20 14:00 |只看该作者
哈,在坛子上大概找到答案了:
http://bbs.chinaunix.net/thread-1804102-2-1.html

研究研究。

论坛徽章:
780
金牛座
日期:2014-02-26 17:49:58水瓶座
日期:2014-02-26 18:10:15白羊座
日期:2014-04-15 19:29:52寅虎
日期:2014-04-17 19:43:21酉鸡
日期:2014-04-19 21:24:10子鼠
日期:2014-04-22 13:55:24卯兔
日期:2014-04-22 14:20:58亥猪
日期:2014-04-22 16:13:09狮子座
日期:2014-05-05 22:31:17摩羯座
日期:2014-05-06 10:32:53处女座
日期:2014-05-12 09:23:11子鼠
日期:2014-05-21 18:21:27
4 [报告]
发表于 2013-12-20 14:20 |只看该作者
本帖最后由 Herowinter 于 2013-12-20 14:20 编辑

正则里面好像有个叫平衡组的
用堆栈来解决这种匹配问题,但
个人没怎么用过,只能友情帮顶了。

论坛徽章:
0
5 [报告]
发表于 2013-12-20 16:41 |只看该作者
Herowinter 发表于 2013-12-20 14:20
正则里面好像有个叫平衡组的
用堆栈来解决这种匹配问题,但
个人没怎么用过,只能友情帮顶了。


谢谢,先考虑用动态正则表达式试试。

论坛徽章:
145
技术图书徽章
日期:2013-10-01 15:32:13戌狗
日期:2013-10-25 13:31:35金牛座
日期:2013-11-04 16:22:07子鼠
日期:2013-11-18 18:48:57白羊座
日期:2013-11-29 10:09:11狮子座
日期:2013-12-12 09:57:42白羊座
日期:2013-12-24 16:24:46辰龙
日期:2014-01-08 15:26:12技术图书徽章
日期:2014-01-17 13:24:40巳蛇
日期:2014-02-18 14:32:59未羊
日期:2014-02-20 14:12:13白羊座
日期:2014-02-26 12:06:59
6 [报告]
发表于 2013-12-20 16:49 |只看该作者
回复 1# felonwan


How about this

$ awk 'BEGIN{FS="";split("=,;+-*/",x,"");for(n in x)k[x[n]]=1}{c=0;s[c]=t[c]="";for(n=0;n++<NF;){if($n in k){s[c]=s[c]t[c];if(p[c]==1){p[c]=0;s[c]=s[c]")"}s[c]=s[c]$n;t[c]=""}else{if($n=="("){s[c]=s[c]t[c];t[c]=$n;c++;s[c]=t[c]=""}if($n==")"){t[c-1]=s[c]t[c];c--}if($n=="^"){p[c]=1;s[c]=s[c]" pow("t[c]",";t[c]=$n="";}t[c]=t[c]$n}}print s[c]}' FILE
c= b /(a-b) * pow((a+b*(a-b)) , (b-a) )*a;
printf("%lf\t%lf\t%lf\t%lf\n", pow(10 , 10), pow(10.11 , 11), pow( a , 2), pow(a , n), pow((a+b) , 2),  pow((a+b) , (b-a)), pow(2 , (a+b)), pow( 2.0 , (a+b));

论坛徽章:
0
7 [报告]
发表于 2013-12-20 17:03 |只看该作者
本帖最后由 felonwan 于 2013-12-20 17:04 编辑

括号配对的问题确实是解决了。

不过第一次写perl,它的正则表达式和sed还不太一样,不知道怎么匹配多个空格和表示“\(……\)”选定的内容。。。

#!/usr/bin/perl
my $str="c= b /(a-b)*((d+(c+e))*a+b*(a-b))^(b-a) *a";
my $levelN;
$levelN = qr/ (?> [^()]+ | \( (??{ $levelN }) \) )* /x;
$str=~ s/\($levelN\)\^\($levelN\)/pow(\1,\2)/g;
print $str."\n";

它的结果是:
c= b /(a-b)*pow(,) *a

论坛徽章:
0
8 [报告]
发表于 2013-12-20 17:08 |只看该作者
太牛了!!!
虽不明,但觉厉!

坐等sed版本。

jason680 发表于 2013-12-20 16:49
回复 1# felonwan

论坛徽章:
145
技术图书徽章
日期:2013-10-01 15:32:13戌狗
日期:2013-10-25 13:31:35金牛座
日期:2013-11-04 16:22:07子鼠
日期:2013-11-18 18:48:57白羊座
日期:2013-11-29 10:09:11狮子座
日期:2013-12-12 09:57:42白羊座
日期:2013-12-24 16:24:46辰龙
日期:2014-01-08 15:26:12技术图书徽章
日期:2014-01-17 13:24:40巳蛇
日期:2014-02-18 14:32:59未羊
日期:2014-02-20 14:12:13白羊座
日期:2014-02-26 12:06:59
9 [报告]
发表于 2013-12-20 17:10 |只看该作者
回复 7# felonwan

$str=~ s/\($levelN\)\^\($levelN\)/pow(\1,\2)/g;
change to
$str=~ s/($levelN)\s*\^\s*($levelN)/pow(\1,\2)/g;   # usually, we use $1,$2 in Perl

   

论坛徽章:
0
10 [报告]
发表于 2013-12-20 17:14 |只看该作者
jason680 发表于 2013-12-20 16:49
How about this

$ awk 'BEGIN{FS="";split("=,;+-*/",x,"";for(n in x)k[x[n]]=1}{c=0;s[c]=t[c]="";for(n=0;n++<NF{if($n in k){s[c]=s[c]t[c];if(p[c]==1){p[c]=0;s[c]=s[c]""}s[c]=s[c]$n;t[c]=""}else{if($n=="("{s[c]=s[c]t[c];t[c]=$n;c++;s[c]=t[c]=""}if($n==""{t[c-1]=s[c]t[c];c--}if($n=="^"{p[c]=1;s[c]=s[c]" pow("t[c]",";t[c]=$n="";}t[c]=t[c]$n}}print s[c]}' FILE


有点小问题,好像是里面只考虑了括号匹配,把不是“^”左右的也去掉了。
不管怎样,还是很感谢。
main(){
……
}

成了:
main
……
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP