免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 3688 | 回复: 12

[文本处理] 如何用AWK或sed或Perl替换这样的文本?高手测试 :) [复制链接]

论坛徽章:
0
发表于 2012-12-13 13:32 |显示全部楼层
本帖最后由 预言家 于 2012-12-13 14:26 编辑

想把乘法符号 "*" 替换成 "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))

论坛徽章:
2
射手座
日期:2014-10-10 15:59:4715-16赛季CBA联赛之上海
日期:2016-03-03 10:27:14
发表于 2012-12-14 01:53 |显示全部楼层
这已经不是简单的替换吧,应该是写一个命令解释器

论坛徽章:
0
发表于 2012-12-14 04:41 |显示全部楼层
yinyuemi 发表于 2012-12-14 01:53
这已经不是简单的替换吧,应该是写一个命令解释器


可以讲讲怎样写一个处理这个简单算法的命令解释器吗?

论坛徽章:
3
CU十二周年纪念徽章
日期:2013-10-24 15:41:34子鼠
日期:2013-12-14 14:57:19射手座
日期:2014-04-25 21:23:23
发表于 2012-12-14 08:54 |显示全部楼层
yinyuemi 发表于 2012-12-14 01:53
这已经不是简单的替换吧,应该是写一个命令解释器

同意~~
我用平衡组只能取出所有符合要求的元素,替换的话 就麻烦了。。替换还要嵌套回去

论坛徽章:
93
2015年辞旧岁徽章
日期:2019-10-10 10:51:15CU大牛徽章
日期:2014-02-21 14:21:56CU十二周年纪念徽章
日期:2020-10-15 16:55:55CU大牛徽章
日期:2014-02-21 14:22:07羊年新春福章
日期:2019-10-10 10:51:39CU大牛徽章
日期:2019-10-10 10:55:38季节之章:春
日期:2020-10-15 16:57:40ChinaUnix元老
日期:2019-10-10 10:54:42季节之章:冬
日期:2019-10-10 10:57:17CU大牛徽章
日期:2014-02-21 14:22:52CU大牛徽章
日期:2014-03-13 10:40:30CU大牛徽章
日期:2014-02-21 14:23:15
发表于 2012-12-14 10:12 |显示全部楼层
括号和你的结果有此许不同,你检查检查,另外从简考虑,使用 /([a-z]+\([^()^]+\))\^([0-9])/ 的正则,所以暂不支持a(a(i))^2这样的嵌套格式,只支持 a(i)^2 的单层格式,如果有需要你再改进这个正则就行了:
  1. [seesea2517@UC ~]# awk -f a.awk a.txt
  2. 原始:5*a(i)*a(j)*(a(k1)+3*a(k2))
  3. 替换:5*tensor(tensor(a(i),a(j)),(a(k1)+3*a(k2)))
  4. -------------
  5. 原始:a(i)^2*a(j)^2
  6. 替换:tensor(p_tensor(2,a(i)),p_tensor(2,a(j)))
  7. -------------
  8. 原始: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))

  9. 替换:3*p_tensor(2,a(3))+6*tensor(p_tensor(2,a(1)),(5*p_tensor(2,a(2))-2*a(4)))+
  10. 6*tensor(a(2),a(4))+6*tensor(a(1),(-4*tensor(a(2),a(3))+a(5)))
  11. -------------
  12. 原始:5*a(2)^2-2*a(4)
  13. 替换:5*p_tensor(2,a(2))-2*a(4)
  14. -------------

  15. [seesea2517@UC ~]# cat a.txt
  16. 5*a(i)*a(j)*(a(k1)+3*a(k2))
  17. a(i)^2*a(j)^2
  18. 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))
  19. 5*a(2)^2-2*a(4)
  20. [seesea2517@UC ~]# cat a.awk
  21. function tensor(line, _ARGEND_, ar, len, i, str, flag, ar_tokens, count, result,
  22. temp)
  23. {
  24.     count = 0
  25.     str  = ""
  26.     flag = 0
  27.     i = 1
  28.     len  = split(line, ar, "")

  29.     if (ar[1] == "(")
  30.     {
  31.         if (ar[len] != ")")
  32.         {
  33.             print "括号不匹配。"
  34.             exit
  35.         }

  36.         ++i
  37.         --len
  38.     }

  39.     for (; i <= len; ++i)
  40.     {
  41.         if (ar[i] == "(")
  42.             flag++

  43.         if (ar[i] == ")")
  44.             flag--

  45.         if (flag < 0)
  46.         {
  47.             print "括号不匹配。"
  48.             exit
  49.         }

  50.         if (flag == 0 && (ar[i] ~ /[+*/]/ || (ar[i] == "-" && ar[i-1] ~ /[0-9)]/
  51. )))
  52.         {
  53.             ar_tokens[count++] = ar[i]
  54.             str = ""
  55.             continue
  56.         }

  57.         str = str""ar[i]
  58.         if (i == len || (ar[i+1] ~ /[-+*/]/ && flag == 0))
  59.         {
  60.             if (str ~ /^\(/)
  61.             {
  62.                 ar_tokens[count++] = "("tensor(str)")"
  63.             } else {
  64.                 ar_tokens[count++] = str
  65.             }
  66.         }
  67.     }

  68.     result = ""
  69.     temp = ""
  70.     for (i = 0; i < count; ++i)
  71.     {
  72.         if (temp == "")
  73.             temp = ar_tokens[i]

  74.         if (ar_tokens[i+1] == "*" && temp !~ /^[-0-9]+$|^$/)
  75.         {
  76.             temp = "tensor("temp","ar_tokens[i+2]")"
  77.             i += 2

  78.             if (i < count)
  79.             {
  80.                 i--
  81.                 continue
  82.             }
  83.         }

  84.         result = result""temp
  85.         temp = ""
  86.     }

  87.     return result
  88. }

  89. BEGIN {
  90.     FS=""
  91. }

  92. {
  93.     print "原始:" $0
  94.     print "替换:" gensub(/([a-z]+\([^()^]+\))\^([0-9])/, "p_tensor(\\2,\\1)", "g", tensor($0))
  95.     print "-------------"
  96. }
复制代码

论坛徽章:
93
2015年辞旧岁徽章
日期:2019-10-10 10:51:15CU大牛徽章
日期:2014-02-21 14:21:56CU十二周年纪念徽章
日期:2020-10-15 16:55:55CU大牛徽章
日期:2014-02-21 14:22:07羊年新春福章
日期:2019-10-10 10:51:39CU大牛徽章
日期:2019-10-10 10:55:38季节之章:春
日期:2020-10-15 16:57:40ChinaUnix元老
日期:2019-10-10 10:54:42季节之章:冬
日期:2019-10-10 10:57:17CU大牛徽章
日期:2014-02-21 14:22:52CU大牛徽章
日期:2014-03-13 10:40:30CU大牛徽章
日期:2014-02-21 14:23:15
发表于 2012-12-14 10:14 |显示全部楼层
屏幕宽度不够换行了,修正一下:
  1. [seesea2517@UC ~]# awk -f a.awk a.txt
  2. 原始:5*a(i)*a(j)*(a(k1)+3*a(k2))
  3. 替换:5*tensor(tensor(a(i),a(j)),(a(k1)+3*a(k2)))
  4. -------------
  5. 原始:a(i)^2*a(j)^2
  6. 替换:tensor(p_tensor(2,a(i)),p_tensor(2,a(j)))
  7. -------------
  8. 原始: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))

  9. 替换: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)))
  10. -------------
  11. 原始:5*a(2)^2-2*a(4)
  12. 替换:5*p_tensor(2,a(2))-2*a(4)
  13. -------------

  14. [seesea2517@UC ~]# cat a.txt
  15. 5*a(i)*a(j)*(a(k1)+3*a(k2))
  16. a(i)^2*a(j)^2
  17. 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))
  18. 5*a(2)^2-2*a(4)
  19. [seesea2517@UC ~]# cat a.awk
  20. function tensor(line, _ARGEND_, ar, len, i, str, flag, ar_tokens, count, result, temp)
  21. {
  22.     count = 0
  23.     str  = ""
  24.     flag = 0
  25.     i = 1
  26.     len  = split(line, ar, "")

  27.     if (ar[1] == "(")
  28.     {
  29.         if (ar[len] != ")")
  30.         {
  31.             print "括号不匹配。"
  32.             exit
  33.         }

  34.         ++i
  35.         --len
  36.     }

  37.     for (; i <= len; ++i)
  38.     {
  39.         if (ar[i] == "(")
  40.             flag++

  41.         if (ar[i] == ")")
  42.             flag--

  43.         if (flag < 0)
  44.         {
  45.             print "括号不匹配。"
  46.             exit
  47.         }

  48.         if (flag == 0 && (ar[i] ~ /[+*/]/ || (ar[i] == "-" && ar[i-1] ~ /[0-9)]/)))
  49.         {
  50.             ar_tokens[count++] = ar[i]
  51.             str = ""
  52.             continue
  53.         }

  54.         str = str""ar[i]
  55.         if (i == len || (ar[i+1] ~ /[-+*/]/ && flag == 0))
  56.         {
  57.             if (str ~ /^\(/)
  58.             {
  59.                 ar_tokens[count++] = "("tensor(str)")"
  60.             } else {
  61.                 ar_tokens[count++] = str
  62.             }
  63.         }
  64.     }

  65.     result = ""
  66.     temp = ""
  67.     for (i = 0; i < count; ++i)
  68.     {
  69.         if (temp == "")
  70.             temp = ar_tokens[i]

  71.         if (ar_tokens[i+1] == "*" && temp !~ /^[-0-9]+$|^$/)
  72.         {
  73.             temp = "tensor("temp","ar_tokens[i+2]")"
  74.             i += 2

  75.             if (i < count)
  76.             {
  77.                 i--
  78.                 continue
  79.             }
  80.         }

  81.         result = result""temp
  82.         temp = ""
  83.     }

  84.     return result
  85. }

  86. BEGIN {
  87.     FS=""
  88. }

  89. {
  90.     print "原始:" $0
  91.     print "替换:" gensub(/([a-z]+\([^()^]+\))\^([0-9])/, "p_tensor(\\2,\\1)", "g", tensor($0))
  92.     print "-------------"
  93. }
复制代码

论坛徽章:
0
发表于 2012-12-14 11:05 |显示全部楼层
很好很强大 搬来板凳细看

seesea2517 发表于 2012-12-14 10:14
屏幕宽度不够换行了,修正一下:

论坛徽章:
93
2015年辞旧岁徽章
日期:2019-10-10 10:51:15CU大牛徽章
日期:2014-02-21 14:21:56CU十二周年纪念徽章
日期:2020-10-15 16:55:55CU大牛徽章
日期:2014-02-21 14:22:07羊年新春福章
日期:2019-10-10 10:51:39CU大牛徽章
日期:2019-10-10 10:55:38季节之章:春
日期:2020-10-15 16:57:40ChinaUnix元老
日期:2019-10-10 10:54:42季节之章:冬
日期:2019-10-10 10:57:17CU大牛徽章
日期:2014-02-21 14:22:52CU大牛徽章
日期:2014-03-13 10:40:30CU大牛徽章
日期:2014-02-21 14:23:15
发表于 2012-12-14 11:09 |显示全部楼层
回复 7# 预言家


    代码很丑,能不看尽量别看……

论坛徽章:
0
发表于 2012-12-14 11:56 |显示全部楼层
本帖最后由 预言家 于 2012-12-14 11:57 编辑

完美!

在倒数第三行加上"+", 这样当指数为多位数字的时候,也可以匹配
print "替换:" gensub(/([a-z]+\([^()^]+\))\^([0-9]+)/, "p_tensor(\\2,\\1)", "g", tensor($0))


回复 6# seesea2517


   

论坛徽章:
0
发表于 2012-12-14 12:02 |显示全部楼层
seesea2517 发表于 2012-12-14 11:09
回复 7# 预言家


哈 强大就好

以下是用perl写的,只能匹配最简单的情形,没有你的强大

  1. $cat tensor.pl

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

  1. 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 tensor.pl
复制代码
得到

  1.   3*p_tensor(2,a(3))+**6*p_tensor(2,a(1))*(5*p_tensor(2,a(2))**-2*a(4))+6*tensor(a(2), a(4))+6*a(1)*(-4*tensor(a(2), a(3))+a(5))
复制代码
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP