免费注册 查看新帖 |

Chinaunix

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

用PERL如何实现括号的正确匹配,相当于数学中的小括号,请多发表意见!!! [复制链接]

论坛徽章:
3
2015亚冠之阿尔希拉尔
日期:2015-08-15 16:33:2215-16赛季CBA联赛之四川
日期:2016-01-03 13:37:0515-16赛季CBA联赛之四川
日期:2016-06-13 15:53:36
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2010-10-23 22:33 |只看该作者 |倒序浏览
本帖最后由 minirain 于 2010-10-23 22:46 编辑

如式子:
表达式1、{{名称为括号A ...}}......字符串{{......}};
             A                      A                 B      B
表达式2、{{...... .......{{...........}}...........}}
              A               B             B           A
其中A、B为正确匹配的括号名称,......为字符串,一段文字有很多表达示1和表达式2组成,用Perl 正则表达式如何实现括号({{)与回括号(}})AA、BB正确匹配呢?
如表达式1、用$kk =~ s/\{\{  ([^\}]+) \}\}/&Fuction($1)/gxe;  适合表达式1的情况但不适合表达式2的情况;
表达式2、用$kk =~ s/\{\{ (.*) \}\}/&Fuction($1)/gxe;  适合表达式2的情况但不适合表达式1的正确匹配;

与数学优先级高的小括号计算式表达式一样:
1、(2+3)×(4-8)
2、5×(3+8×(3+4))
不知道计算机或者计算器是如何正确匹配计算式小括号配对的???
请大家多给建议或意见!
谢谢大家了!
minirain
20101023

论坛徽章:
46
15-16赛季CBA联赛之四川
日期:2018-03-27 11:59:132015年亚洲杯之沙特阿拉伯
日期:2015-04-11 17:31:45天蝎座
日期:2015-03-25 16:56:49双鱼座
日期:2015-03-25 16:56:30摩羯座
日期:2015-03-25 16:56:09巳蛇
日期:2015-03-25 16:55:30卯兔
日期:2015-03-25 16:54:29子鼠
日期:2015-03-25 16:53:59申猴
日期:2015-03-25 16:53:29寅虎
日期:2015-03-25 16:52:29羊年新春福章
日期:2015-03-25 16:51:212015亚冠之布里斯班狮吼
日期:2015-07-13 10:44:56
2 [报告]
发表于 2010-10-23 22:45 |只看该作者
再复杂也不过是个树,像lisp那样

论坛徽章:
3
2015亚冠之阿尔希拉尔
日期:2015-08-15 16:33:2215-16赛季CBA联赛之四川
日期:2016-01-03 13:37:0515-16赛季CBA联赛之四川
日期:2016-06-13 15:53:36
3 [报告]
发表于 2010-10-23 22:47 |只看该作者
再复杂也不过是个树,像lisp那样
zhlong8 发表于 2010-10-23 22:45



    请问如何实现呢?谢谢!

论坛徽章:
46
15-16赛季CBA联赛之四川
日期:2018-03-27 11:59:132015年亚洲杯之沙特阿拉伯
日期:2015-04-11 17:31:45天蝎座
日期:2015-03-25 16:56:49双鱼座
日期:2015-03-25 16:56:30摩羯座
日期:2015-03-25 16:56:09巳蛇
日期:2015-03-25 16:55:30卯兔
日期:2015-03-25 16:54:29子鼠
日期:2015-03-25 16:53:59申猴
日期:2015-03-25 16:53:29寅虎
日期:2015-03-25 16:52:29羊年新春福章
日期:2015-03-25 16:51:212015亚冠之布里斯班狮吼
日期:2015-07-13 10:44:56
4 [报告]
发表于 2010-10-23 22:53 |只看该作者
以前实现 scheme 的 read 的时候写个类似的。[current, parent] 这样的结构,遇到 '(' 就新加一层变成
[new_current, [current, parent]],遇到 ')' 就消除一层……还要再具体吗

论坛徽章:
3
2015亚冠之阿尔希拉尔
日期:2015-08-15 16:33:2215-16赛季CBA联赛之四川
日期:2016-01-03 13:37:0515-16赛季CBA联赛之四川
日期:2016-06-13 15:53:36
5 [报告]
发表于 2010-10-23 23:02 |只看该作者
以前实现 scheme 的 read 的时候写个类似的。[current, parent] 这样的结构,遇到 '(' 就新加一层变成
[ne ...
zhlong8 发表于 2010-10-23 22:53



    能给个用PERL程序实现的例子,可以吗?

论坛徽章:
46
15-16赛季CBA联赛之四川
日期:2018-03-27 11:59:132015年亚洲杯之沙特阿拉伯
日期:2015-04-11 17:31:45天蝎座
日期:2015-03-25 16:56:49双鱼座
日期:2015-03-25 16:56:30摩羯座
日期:2015-03-25 16:56:09巳蛇
日期:2015-03-25 16:55:30卯兔
日期:2015-03-25 16:54:29子鼠
日期:2015-03-25 16:53:59申猴
日期:2015-03-25 16:53:29寅虎
日期:2015-03-25 16:52:29羊年新春福章
日期:2015-03-25 16:51:212015亚冠之布里斯班狮吼
日期:2015-07-13 10:44:56
6 [报告]
发表于 2010-10-23 23:09 |只看该作者
本帖最后由 zhlong8 于 2010-10-24 00:02 编辑

package T
  1. package T;

  2. use 5.012;
  3. use warnings;

  4. sub new {
  5.     my($class, $parent) = @_;
  6.     bless {
  7.         current => [],
  8.         parent => $parent
  9.     }, $class;
  10. }

  11. sub dec {
  12.     my $self = shift;
  13.     push @{$self->{parent}{current}}, $self->{current};
  14.     $self->{parent};
  15. }

  16. sub add {
  17.     my($self, $val) = @_;
  18.     push @{$self->{current}}, $val;
  19. }

  20. sub top {
  21.     bless {current => [], parent=> []}, shift;
  22. }

  23. 1;
复制代码
实现
  1. use 5.012;
  2. use warnings;
  3. use T;
  4. use Data::Dumper;
  5. use Regexp::Common;

  6. sub parse {
  7.     my $tree = T->top;
  8.     for (@_) {
  9.         given ($_) {
  10.             when ('(') {$tree = T->new($tree)}
  11.             when (')') {$tree = $tree->dec;}
  12.             default {$tree->add($_);}
  13.         }
  14.     }
  15.     say Dumper $tree;
  16. }

  17. sub tokenize {  #功能非常有限
  18.     my $str = shift;
  19.     say "got $str";
  20.     my @all;
  21.     while ($str =~ /\G\s*(\(|\)|$RE{num}{real}|$RE{num}{int}|\w+|[+\-*\/])\s*/g) {
  22.         push @all, $1;
  23.     }
  24.     say "return @all";
  25.     @all;
  26. }

  27. #(define a (+ 343 (* 3323 a)))
  28. parse '(', 'define', 'a', '(', '+', '343', '(', '*', '3323', 'a', ')', ')', ')';
  29. #或者
  30. parse tokenize '(define a (+ 343 (* 3323 a)))'
复制代码
输出
  1. $VAR1 = bless( {
  2.                  'parent' => [],
  3.                  'current' => [
  4.                                 [
  5.                                   'define',
  6.                                   'a',
  7.                                   [
  8.                                     '+',
  9.                                     '343',
  10.                                     [
  11.                                       '*',
  12.                                       '3323',
  13.                                       'a'
  14.                                     ]
  15.                                   ]
  16.                                 ]
  17.                               ]
  18.                }, 'T' );
复制代码
有个Parse::RecDescent 模块,不过我不会用
还有 Regexp::Common::balanced

论坛徽章:
0
7 [报告]
发表于 2010-10-23 23:10 |只看该作者
回复 1# minirain


    这个,单纯只用正则确实不容易啊,如果用堆栈的方式,可能会容易一些

论坛徽章:
46
15-16赛季CBA联赛之四川
日期:2018-03-27 11:59:132015年亚洲杯之沙特阿拉伯
日期:2015-04-11 17:31:45天蝎座
日期:2015-03-25 16:56:49双鱼座
日期:2015-03-25 16:56:30摩羯座
日期:2015-03-25 16:56:09巳蛇
日期:2015-03-25 16:55:30卯兔
日期:2015-03-25 16:54:29子鼠
日期:2015-03-25 16:53:59申猴
日期:2015-03-25 16:53:29寅虎
日期:2015-03-25 16:52:29羊年新春福章
日期:2015-03-25 16:51:212015亚冠之布里斯班狮吼
日期:2015-07-13 10:44:56
8 [报告]
发表于 2010-10-23 23:31 |只看该作者
回复 7# 珞水的大叔


    发现大叔太NB了,8月18到10月23总共65天在线855小时。
855/(65*24) = 54.81%

论坛徽章:
0
9 [报告]
发表于 2010-10-23 23:35 |只看该作者
回复 8# zhlong8


    嘿嘿嘿嘿……

论坛徽章:
0
10 [报告]
发表于 2010-10-25 16:37 |只看该作者
本帖最后由 toniz 于 2010-10-25 16:43 编辑



貌似正则的话比较麻烦。

为了解析嵌套括号,如要完整取到括号信息,需要先把取到的括号变成其它字符,然后取出来后再变回去。

抛砖砸人,正则思路如下:
  1. my $string = "0,0,{0,0},0,{50,50,50,50,{1,2},{3,4},0},0,{0,0}";
  2. 1 while($string =~ s/\{([^{}]*)\}/print "$1\n";'$1';/ee);
复制代码
[etl@dmtest]$ perl tt.tt
0,0
1,2
3,4
50,50,50,50,1,2,3,4,0
0,0


这个是从内括号开始匹配,取出所有括号里面的信息,不足是外括号取内括号内容时候,会失去括号。

如果要做到完整提取,可以考虑用替换,把取出来后的括号替换成其它符号,获取之后再替换回去。

介绍下思路,具体的就不写啦
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP