免费注册 查看新帖 |

Chinaunix

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

perl 处理文本 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2009-09-25 13:54 |只看该作者 |倒序浏览
815 19919
1161 3453
4524 8107
14504 16533
22426 23943
23751 27377
29930 30222


我有如上的数据,第一列可以看成是起始位置,第二列为结束位置,现在想把重复的进行合并,合并后的数据如下
815 19919
22426 27377
29930 30222
请问perl语句应该如何写呢?
新手,多多指教哦!

论坛徽章:
0
2 [报告]
发表于 2009-09-25 14:01 |只看该作者
主要的问题,如果数据是部分覆盖,怎么处理?

论坛徽章:
0
3 [报告]
发表于 2009-09-25 14:04 |只看该作者

回复 #2 dugu072 的帖子

22426 23943
23751 27377
如这种的,则22426做头,27377作尾,因为23943覆盖了23751

论坛徽章:
0
4 [报告]
发表于 2009-09-25 14:55 |只看该作者
把问题想简单了,竟然发现这个匹配还需要个麻烦点的算法,下面这个是示例,肯定还需要改,尤其是数据如果不是你这种从小到大的递增的话,还需要反复几次的筛选匹配。不过对你给的数据,倒是能够正常工作,自己看着完善吧~

use strict;
open( *FH, 'data.txt');
my ($from, $to);
while (<FH>) {
   chomp;
   if (/(\d+)\s+(\d+)/) {
     if($to < $1) {
        $from = $1;
        $to = $2;
        print "$. $from-$to\n";
     }elsif($to >= $1 && $from > $1) {
        $from = $1;
        $to = $to;
        print "$. $from-$to\n";
     }elsif($to >= $1 && $from < $1) {
        $from = $from;
        $to = $to; # 示例而已,如果此种情况,没必要处理
     }
   }
}

论坛徽章:
0
5 [报告]
发表于 2009-09-25 16:07 |只看该作者

回复 #4 dugu072 的帖子

谢谢了,我先试试看,研究一下,我的数据已经按递增排好了,所以不用太麻烦的。
我刚刚学perl,非常感谢你的热心指导!!

论坛徽章:
5
2015年辞旧岁徽章
日期:2015-03-03 16:54:152015年迎新春徽章
日期:2015-03-04 09:50:282015年亚洲杯之朝鲜
日期:2015-03-13 22:47:33IT运维版块每日发帖之星
日期:2016-01-09 06:20:00IT运维版块每周发帖之星
日期:2016-03-07 16:27:44
6 [报告]
发表于 2009-09-25 21:27 |只看该作者
1161 3453
4524 8107 哪里去了?
LZ想要的结果是什么?

论坛徽章:
5
2015年辞旧岁徽章
日期:2015-03-03 16:54:152015年迎新春徽章
日期:2015-03-04 09:50:282015年亚洲杯之朝鲜
日期:2015-03-13 22:47:33IT运维版块每日发帖之星
日期:2016-01-09 06:20:00IT运维版块每周发帖之星
日期:2016-03-07 16:27:44
7 [报告]
发表于 2009-09-25 22:45 |只看该作者
这样?
  1. #!/bin/perl
  2. use warnings;
  3. use strict;

  4. open (IN,"urfile") or die "Can't open file: $!";
  5. my($from,$to);

  6. while (<IN>) {
  7.   if(/(\d+)\s+(\d+)/) {
  8.     if ($1 > $to) {
  9.       print "$from $to \n" if $to;
  10.       ($from,$to) = ($1,$2);
  11.     } elsif ($2 > $to) {
  12.       $to = $2;
  13.     }
  14.   }
  15. }

  16. print "$from $to \n";
复制代码

论坛徽章:
1
技术图书徽章
日期:2014-03-06 15:29:50
8 [报告]
发表于 2009-09-26 00:21 |只看该作者
#!/usr/bin/perl

use warnings;
use strict;

my %records;
my $filename = $ARGV[0];
open FILE, $filename or die "Can't open words $!, $filename\n";
while(<FILE>)
{
    chomp;
    my ($start, $end) = split;
    $records{int $start} = int
$end;   
}
close FILE;

my @starts = sort {$a <=> $b} keys %records;
my $index = 0;

while($index < $#starts)

{
    if ($starts[$index + 1] < $records{$starts[$index]})
    {
        $records{$starts[$index]} = $records{$starts[$index + 1]} if $records{$starts[$index]} < $records{$starts[$index + 1]};
        splice @starts, $index + 1, 1;
        $index--;        
    }
    $index++;
}

foreach (@starts)
{
    print "$_--$records{$_} ";
}


可能写的比较笨,但是功能实现了,简单测试通过。

假设是左闭右开区间,如果是两边都闭的话,如下加个等号就可以了。
   if ($starts[$index + 1] <= $records{$starts[$index]})

[ 本帖最后由 qshllxfx 于 2009-9-26 00:48 编辑 ]

论坛徽章:
1
技术图书徽章
日期:2014-03-06 15:29:50
9 [报告]
发表于 2009-09-26 00:50 |只看该作者
郁闷的是都转成整形了,sort的时候还要指定做数值比较

论坛徽章:
0
10 [报告]
发表于 2009-09-26 15:28 |只看该作者
我看了一下几位大虾的程序,解决了我的问题,从中也学到了不少新的东东,非常感谢!
不过,dugu072的程序结果和我想要的还有一点差距,可能是我说的不太详细吧;blackold的方法很简单,借鉴了;qshllxfx的方法和我的想法很像,就是我不会写,呵呵,不过结果也是对的。
再次感谢你们,不仅帮助了我,还学习了新知识!
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP