LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
查看: 2373|回复: 14

如何写括号配对的正则表达式?

[复制链接]
发表于 2004-6-9 19:08:29 | 显示全部楼层 |阅读模式
比方说有这样一些字符串,我需要把abc{}中的内容提取出来。

  1. abc{123}->123
  2. abc{123{23a}}->123{23a}
  3. abc{123{}->123{
  4. abc{123}}->[color=red]123[/color]
  5. abc{123{{a}}}{456}->123{{a}}
  6. abc{123{}456{}}123{456}->123{}456{}
复制代码

最好是,如果它内部有没有配对的话,也能检查出来。
发表于 2004-6-9 20:41:43 | 显示全部楼层
我的蠢方法

$roby="abc{123{}";
$roby =~ /\{(.*)\}/;
print "$1";
 楼主| 发表于 2004-6-9 21:16:36 | 显示全部楼层
最初由 roby 发表
我的蠢方法

$roby="abc{123{}";
$roby =~ /\{(.*)\}/;
print "$1";

呵呵,这样不行的, 比方说:abc{123{}}{}将会得到123{}}{而我想要的是123{},也怪我没有写清楚要求。
发表于 2004-6-9 21:32:29 | 显示全部楼层

我明白你的意思了
我再想想

最近正在看正则
这东西实在是有点博大精深,现在还处于头晕晕的状态
发表于 2004-6-9 22:26:36 | 显示全部楼层
试试看

#!/usr/bin/perl
$roby=<stdin>;
chomp $roby;
if ($roby =~ /\{(.*)\}\{/) {
        print "$1\n";
}else{
if ($roby =~ /\{(.*)\}/) {
        print "$1";
}
}
 楼主| 发表于 2004-6-9 22:34:30 | 显示全部楼层
最初由 roby 发表
试试看

#!/usr/bin/perl
$roby=<stdin>;
chomp $roby;
if ($roby =~ /\{(.*)\}\{/) {
        print "$1\n";
}else{
if ($roby =~ /\{(.*)\}/) {
        print "$1";
}
}

看我新加的那一句
发表于 2004-6-9 22:50:18 | 显示全部楼层

如果把你
abc{123{}->123{
abc{123}}->123}
这种没匹对的跟
abc{123{}456{}}123{456}->123{}456{}再结合起来
那就更复杂了
我是搞不定了
头晕
我还搬把小板凳
看那位老大能够解决
好从中学点东西
 楼主| 发表于 2004-6-9 23:12:55 | 显示全部楼层
或许可以用x运算符解决
现在没空了,等什么时候空下来再来研究一下。
发表于 2004-6-10 01:22:16 | 显示全部楼层
当{}全部成对的情况已经解决

abc{123{}->123{
abc{123}}->123}
这种情况也有了点头绪
先睡觉
明天起来后再继续
 楼主| 发表于 2004-6-10 02:43:29 | 显示全部楼层
最初由 roby 发表
当{}全部成对的情况已经解决

abc{123{}->123{
abc{123}}->123}
这种情况也有了点头绪
先睡觉
明天起来后再继续

强的。我现在只解决了成对的情况。这是代码,实现得很不好

  1. #!/usr/bin/perl -w
  2. open IN, $ARGV[0] or die("Can't open file: $!\n");
  3. my @array=<IN>;
  4. foreach my $content(@array){
  5.     chomp $content;
  6.     my $matched = undef;
  7.     my @result=();
  8.     for(my $i= length($content); $i>=0; $i--){
  9.         my $pre = "[^{}]*{[^{}]*" x $i;
  10.         my $suf = "[^{}]*}[^{}]*" x $i;
  11.         if($content=~m#abc{(([^{}]*($pre {[^{}]*}$suf )*[^{}]*)*)}#x){
  12.             push @result, $1;
  13.             $matched = 1;
  14.         }
  15.     }
  16.     print "Matched: $content -> ", &lengest(\@result), "\n" if $matched;
  17.     print "Unmatched: $content\n" unless $matched;
  18. }
  19. close(IN);

  20. sub lengest
  21. {
  22.     my $array = $_[0];
  23.     my $len = 0;
  24.     my $ret = undef;
  25.     foreach(@$array){
  26.         if($len < length($_)){
  27.             $ret = $_;
  28.             $len = length($_);
  29.         }
  30.     }
  31.     return $ret;
  32. }
  33.         
复制代码

所使用的测试文件:
  1. abc{}
  2. abc{abc}
  3. abc{abc{}}
  4. abc{abc{{abc}}}
  5. abc{abc{b}a{b}d}
  6. abc{abc{d}a{b}d}{a}
  7. abc{abc{d}a{b}d}db{a}
复制代码

输出结果:

  1. Use of uninitialized value in print at ./gnum.pl line 16, <IN> line 7.
  2. Matched: abc{} ->
  3. Matched: abc{abc} -> abc
  4. Matched: abc{abc{}} -> abc{}
  5. Matched: abc{abc{{abc}}} -> abc{{abc}}
  6. Matched: abc{abc{b}a{b}d} -> abc{b}a{b}d
  7. Matched: abc{abc{d}a{b}d}{a} -> abc{d}a{b}d
  8. Matched: abc{abc{d}a{b}d}db{a} -> abc{d}a{b}d
复制代码

那个警告,我一直没看出来是哪里出问题。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表