免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
楼主: sunzhiguolu
打印 上一主题 下一主题

如何选取年份 [复制链接]

论坛徽章:
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
11 [报告]
发表于 2016-05-16 21:24 |只看该作者
回复 1# sunzhiguolu


>> ...要精确打印出相隔10年之内行

何来精确??!!

1999121   =>1999/1/21
1999121   =>1999/12/1

1999121 2000111 有一年吗?

评分

参与人数 1信誉积分 +10 收起 理由
sunzhiguolu + 10 向您学习, 谢谢您!!!

查看全部评分

论坛徽章:
307
程序设计版块每周发帖之星
日期:2016-04-08 00:41:33操作系统版块每日发帖之星
日期:2015-09-02 06:20:00每日论坛发贴之星
日期:2015-09-02 06:20:00程序设计版块每日发帖之星
日期:2015-09-04 06:20:00每日论坛发贴之星
日期:2015-09-04 06:20:00每周论坛发贴之星
日期:2015-09-06 22:22:00程序设计版块每日发帖之星
日期:2015-09-09 06:20:00程序设计版块每日发帖之星
日期:2015-09-19 06:20:00程序设计版块每日发帖之星
日期:2015-09-20 06:20:00每日论坛发贴之星
日期:2015-09-20 06:20:00程序设计版块每日发帖之星
日期:2015-09-22 06:20:00程序设计版块每日发帖之星
日期:2015-09-24 06:20:00
12 [报告]
发表于 2016-05-16 21:34 |只看该作者
回复 11# jason680
还是大神您考虑的周全, 我没有想到. 光想着怎么能够获取到正确的年份信息. 谢谢点醒梦中人.

   

论坛徽章:
307
程序设计版块每周发帖之星
日期:2016-04-08 00:41:33操作系统版块每日发帖之星
日期:2015-09-02 06:20:00每日论坛发贴之星
日期:2015-09-02 06:20:00程序设计版块每日发帖之星
日期:2015-09-04 06:20:00每日论坛发贴之星
日期:2015-09-04 06:20:00每周论坛发贴之星
日期:2015-09-06 22:22:00程序设计版块每日发帖之星
日期:2015-09-09 06:20:00程序设计版块每日发帖之星
日期:2015-09-19 06:20:00程序设计版块每日发帖之星
日期:2015-09-20 06:20:00每日论坛发贴之星
日期:2015-09-20 06:20:00程序设计版块每日发帖之星
日期:2015-09-22 06:20:00程序设计版块每日发帖之星
日期:2015-09-24 06:20:00
13 [报告]
发表于 2016-05-16 21:38 |只看该作者
穷举了一个, 只能是玩玩了. 正如 Jason680 大神所说, 这日期咋能精确呀!
  1. #!/usr/bin/perl
  2. use strict;
  3. use warnings;

  4. my ($sRegx) = (qr/(0?[1-9]|1[0-2])([1-2]?[0-9]|0?[1-9]|3[01])/);
  5. while (<DATA>){
  6.     next if (/\A\s*\z/);
  7.     my $sYears = $_;
  8.     my @aYears = ([0..2], [0..2]);

  9.     foreach my $sIdx (0 .. $#aYears){
  10.         @{$aYears[$sIdx]}[1,2] = ($1, $2) if (/$sRegx\b/);
  11.         $aYears[$sIdx][0] = substr ($_, 0, $-[1]);
  12.         s/\d+\s*//;
  13.     }

  14.     foreach my $raYear (@aYears){
  15.         if (length $raYear->[0] == 2){
  16.             if ($raYear->[0] =~ /\A([01]\d+)/){
  17.                 $raYear->[0] = "20$1";
  18.                 next;
  19.             }
  20.             $raYear->[0] = "19$raYear->[0]";
  21.         }
  22.     }

  23.     my ($rA, $rB) = splice (@aYears);
  24.     next if (abs ($rA->[0] - $rB->[0]) > 10);
  25.     next if ($rA->[0] - $rB->[0] == 10 and $rA->[1] > $rB->[1]);
  26.     next if ($rB->[0] - $rA->[0] == 10 and $rB->[1] > $rA->[1]);
  27.     next if ($rA->[0] - $rB->[0] == 10 and $rA->[1] == $rB->[1] and $rA->[-1] > $rB->[-1]);
  28.     next if ($rB->[0] - $rA->[0] == 10 and $rB->[1] == $rA->[1] and $rB->[-1] > $rA->[-1]);
  29.     print $sYears;
  30. }

  31. __DATA__
  32. 1987913 19970912
  33. 2000315 20100316

  34. 2004410 20140410

  35. 1999121 20050806
  36. 20050806 1999121

  37. 19901019 2016515

  38. 99121 050806
复制代码

论坛徽章:
307
程序设计版块每周发帖之星
日期:2016-04-08 00:41:33操作系统版块每日发帖之星
日期:2015-09-02 06:20:00每日论坛发贴之星
日期:2015-09-02 06:20:00程序设计版块每日发帖之星
日期:2015-09-04 06:20:00每日论坛发贴之星
日期:2015-09-04 06:20:00每周论坛发贴之星
日期:2015-09-06 22:22:00程序设计版块每日发帖之星
日期:2015-09-09 06:20:00程序设计版块每日发帖之星
日期:2015-09-19 06:20:00程序设计版块每日发帖之星
日期:2015-09-20 06:20:00每日论坛发贴之星
日期:2015-09-20 06:20:00程序设计版块每日发帖之星
日期:2015-09-22 06:20:00程序设计版块每日发帖之星
日期:2015-09-24 06:20:00
14 [报告]
发表于 2016-05-16 21:39 |只看该作者
输出结果:
1987913 19970912
2004410 20140410
1999121 20050806
20050806 1999121
99121 050806
050806 99121

论坛徽章:
307
程序设计版块每周发帖之星
日期:2016-04-08 00:41:33操作系统版块每日发帖之星
日期:2015-09-02 06:20:00每日论坛发贴之星
日期:2015-09-02 06:20:00程序设计版块每日发帖之星
日期:2015-09-04 06:20:00每日论坛发贴之星
日期:2015-09-04 06:20:00每周论坛发贴之星
日期:2015-09-06 22:22:00程序设计版块每日发帖之星
日期:2015-09-09 06:20:00程序设计版块每日发帖之星
日期:2015-09-19 06:20:00程序设计版块每日发帖之星
日期:2015-09-20 06:20:00每日论坛发贴之星
日期:2015-09-20 06:20:00程序设计版块每日发帖之星
日期:2015-09-22 06:20:00程序设计版块每日发帖之星
日期:2015-09-24 06:20:00
15 [报告]
发表于 2016-05-17 11:08 |只看该作者
我将发生歧义的日期部分, 修改了下.
在进行日期比较的时候, 发现有好多冗余的代码, 不知道如何进行优化下, 还请大家指点, 谢谢大家...
  1. #!/usr/bin/perl
  2. use strict;
  3. use warnings;

  4. my ($sRegx) = (qr/(0?[1-9]|1[0-2])([12][0-9]|0?[1-9]|3[01])/);
  5. while (<DATA>){
  6.     next if (m/\A\s*\z/);
  7.     my @aDate = ({},{});
  8.     my $sYears = $_;

  9.     foreach my $sIdx (0 .. $#aDate){
  10.         ($aDate[$sIdx]{'M'}, $aDate[$sIdx]{'D'}) = ($1, $2) if (m/$sRegx\b/);
  11.         $aDate[$sIdx]{'Y'} = substr ($_, 0, $-[1]);
  12.         if (length $aDate[$sIdx]{'Y'} == 2){
  13.             if ($aDate[$sIdx]{'Y'} =~ m/\A([01]\d+)/){
  14.                 $aDate[$sIdx]{'Y'} = "20$1";
  15.             }else{
  16.                 $aDate[$sIdx]{'Y'} = "19$aDate[$sIdx]{'Y'}";
  17.             }
  18.         }
  19.         s/\d+\s*//;
  20.     }

  21.     my ($Ya, $Yb) = splice (@aDate);
  22.     next if (abs ($Ya->{'Y'} - $Yb->{'Y'}) > 10);
  23.     next if ($Ya->{'Y'} - $Yb->{'Y'} == 10 and $Ya->{'M'} > $Yb->{'M'});
  24.     next if ($Yb->{'Y'} - $Ya->{'Y'} == 10 and $Yb->{'M'} > $Ya->{'M'});
  25.     next if ($Ya->{'Y'} - $Yb->{'Y'} == 10 and $Ya->{'M'} == $Yb->{'M'} and $Ya->{'D'} > $Yb->{'D'});
  26.     next if ($Yb->{'Y'} - $Ya->{'Y'} == 10 and $Yb->{'M'} == $Ya->{'M'} and $Yb->{'D'} > $Ya->{'D'});
  27.     print $sYears;
  28. }

  29. __DATA__
  30. 19870913 1997912
  31. 20000315 20100316

  32. 2004410 20140410

  33. 19990121 20050806
  34. 20050806 19990121

  35. 19901019 2016515

  36. 991201 050806
复制代码

论坛徽章:
307
程序设计版块每周发帖之星
日期:2016-04-08 00:41:33操作系统版块每日发帖之星
日期:2015-09-02 06:20:00每日论坛发贴之星
日期:2015-09-02 06:20:00程序设计版块每日发帖之星
日期:2015-09-04 06:20:00每日论坛发贴之星
日期:2015-09-04 06:20:00每周论坛发贴之星
日期:2015-09-06 22:22:00程序设计版块每日发帖之星
日期:2015-09-09 06:20:00程序设计版块每日发帖之星
日期:2015-09-19 06:20:00程序设计版块每日发帖之星
日期:2015-09-20 06:20:00每日论坛发贴之星
日期:2015-09-20 06:20:00程序设计版块每日发帖之星
日期:2015-09-22 06:20:00程序设计版块每日发帖之星
日期:2015-09-24 06:20:00
16 [报告]
发表于 2016-05-17 11:11 |只看该作者
本帖最后由 sunzhiguolu 于 2016-05-17 11:16 编辑

就是在代码的 25~29 行处 (判断不符合条件的日期), 另外, 如果其他地方需要改进的话也请大家指点, 谢谢大家...

论坛徽章:
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
17 [报告]
发表于 2016-05-17 18:11 |只看该作者
本帖最后由 jason680 于 2016-05-17 18:18 编辑

回复 15# sunzhiguolu

How about this easy way ...

while (<DATA>){
    next if (m/\A\s*\z/);

    my $sLine = $_;
    my @aDay;
    foreach(split){

      # 1997912 => 19970912
      #   99121 =>   990121
      s/^((..)+)(...)$/${1}0${3}/;
      
      #991201 => 19991201  , 99 >= 18 , 1918 ~ 1999
      #050806 => 20050806  , 05 <  18 , 2000 ~ 2017
      s/^(..)(....)$/19+($1<18)."$1$2"/e;
   
      push @aDay, $_;
    }
    #print "@aDay\n";
    if($aDay[0] < $aDay[1]){
      @aDay[0,1] = @aDay[1,0];
    }
    #      10 years(YYMMDD) => 100000   
    if( $aDay[0] <= $aDay[1] +  100000){  #
ONLY for years(YY0000)
      print $sLine;
    }
}

   

评分

参与人数 1信誉积分 +10 收起 理由
sunzhiguolu + 10 您这个正则用的神了!!!

查看全部评分

论坛徽章:
307
程序设计版块每周发帖之星
日期:2016-04-08 00:41:33操作系统版块每日发帖之星
日期:2015-09-02 06:20:00每日论坛发贴之星
日期:2015-09-02 06:20:00程序设计版块每日发帖之星
日期:2015-09-04 06:20:00每日论坛发贴之星
日期:2015-09-04 06:20:00每周论坛发贴之星
日期:2015-09-06 22:22:00程序设计版块每日发帖之星
日期:2015-09-09 06:20:00程序设计版块每日发帖之星
日期:2015-09-19 06:20:00程序设计版块每日发帖之星
日期:2015-09-20 06:20:00每日论坛发贴之星
日期:2015-09-20 06:20:00程序设计版块每日发帖之星
日期:2015-09-22 06:20:00程序设计版块每日发帖之星
日期:2015-09-24 06:20:00
18 [报告]
发表于 2016-05-17 19:24 |只看该作者
回复 17# jason680
开眼了, 还能这么做加法. 谢谢您指点, 学习了, 学了好几手!!!

   

论坛徽章:
307
程序设计版块每周发帖之星
日期:2016-04-08 00:41:33操作系统版块每日发帖之星
日期:2015-09-02 06:20:00每日论坛发贴之星
日期:2015-09-02 06:20:00程序设计版块每日发帖之星
日期:2015-09-04 06:20:00每日论坛发贴之星
日期:2015-09-04 06:20:00每周论坛发贴之星
日期:2015-09-06 22:22:00程序设计版块每日发帖之星
日期:2015-09-09 06:20:00程序设计版块每日发帖之星
日期:2015-09-19 06:20:00程序设计版块每日发帖之星
日期:2015-09-20 06:20:00每日论坛发贴之星
日期:2015-09-20 06:20:00程序设计版块每日发帖之星
日期:2015-09-22 06:20:00程序设计版块每日发帖之星
日期:2015-09-24 06:20:00
19 [报告]
发表于 2016-05-17 20:48 |只看该作者
本帖最后由 sunzhiguolu 于 2016-05-18 00:29 编辑

非常感谢 Jason680 大神指点, 重新修改了下.
  1. #!/usr/bin/perl
  2. use strict;
  3. use warnings;

  4. while (<DATA>){
  5.     next if (m/\A\s*\z/);
  6.     my @aDate = ({},{});
  7.     my $sOffset = 0;
  8.     my $sLine = $_;

  9.     foreach (split){
  10.         s/\A((?:\d{2})+)(\d{3})\z/${1}0$2/;
  11.         s/\A(\d{2})(\d{4})\z/19+($1<18)."$1$2"/e;
  12.         @{$aDate[$sOffset++]}{'Y','M','D'} = m/\A(\d{4})(\d{2})(\d{2})/g;
  13.     }

  14.     my ($Ya, $Yb) = sort {local $" = ""; "@$b{'Y','M','D'}" cmp "@$a{'Y','M','D'}"} @aDate;
  15.     next if ($Ya->{'Y'} - $Yb->{'Y'} > 10);
  16.     next if ($Ya->{'Y'} - $Yb->{'Y'} == 10 and $Ya->{'M'} > $Yb->{'M'});
  17.     next if ($Ya->{'Y'} - $Yb->{'Y'} == 10 and $Ya->{'M'} == $Yb->{'M'} and $Ya->{'D'} > $Yb->{'D'});
  18.     print $sLine;
  19. }

  20. __DATA__
  21. 19870913 1997912
  22. 20000315 20100316

  23. 2004410 20140410

  24. 19990121 20050806
  25. 20050806 19990121

  26. 19901019 2016515

  27. 991201 050806
复制代码

论坛徽章:
6
15-16赛季CBA联赛之新疆
日期:2016-03-22 22:34:5915-16赛季CBA联赛之山东
日期:2016-04-11 09:08:41程序设计版块每日发帖之星
日期:2016-06-28 06:20:00程序设计版块每日发帖之星
日期:2016-07-19 06:20:00每日论坛发贴之星
日期:2016-07-19 06:20:0015-16赛季CBA联赛之青岛
日期:2016-07-20 22:44:17
20 [报告]
发表于 2016-05-18 00:35 |只看该作者
本帖最后由 RE_HASH 于 2016-05-18 00:45 编辑

$>  cat aa.pl ; perl  aa.pl
sub guessDate
{
  $_ = shift;
  my ($y, $m, $d) = /^((?:19|20)*\d{2}|0?\d{1})([01]?\d)([0-2]?\d|3[01])$/;
  $y +=1900 if ($y < 100);
  $y +=100 if ($y < 1950);
  return sprintf "%4d%02d%02d", $y, $m, $d;
}
printf STDERR "DEBUG INFO:\n______________\n";
while (<DATA>)
{
  chomp;
  @A = map {guessDate($_)} split;

  print STDERR "$_\tConverted to :\t", "@A", ($A[0] + 100000 > $A[1])?"\t< 10 years":"\t> 10 years", "\n" ;
  ($A[0] + 100000 > $A[1]) ? push @{$O->{'10 Years -'}}, $_: push @{$O->{'10 years +'}}, $_  ;
}


printf "OUTPUT:\n______________\n%s", join "\n", @{$O->{'10 Years -'}};

__DATA__
19870913 1997912
20000315 20100316
0411 0411
2004410 20140410
89112 90112
19990121 20050806
20050806 19990121
01121 02122
19901019 2016515
991201 050806

DEBUG INFO:
______________
19870913 1997912        Converted to :  19870913 19970912       < 10 years
20000315 20100316       Converted to :  20000315 20100316       > 10 years
0411 0411       Converted to :  20040101 20040101       < 10 years
2004410 20140410        Converted to :  20040410 20140410       > 10 years
89112 90112     Converted to :  19891102 19901102       < 10 years
19990121 20050806       Converted to :  19990121 20050806       < 10 years
20050806 19990121       Converted to :  20050806 19990121       < 10 years
01121 02122     Converted to :  20011201 20021202       < 10 years
19901019 2016515        Converted to :  19901019 20160515       > 10 years
991201 050806   Converted to :  19991201 20050806       < 10 years
        Converted to :          < 10 years
OUTPUT:
______________
19870913 1997912
0411 0411
89112 90112
19990121 20050806
20050806 19990121
01121 02122
991201 050806

评分

参与人数 1信誉积分 +10 收起 理由
sunzhiguolu + 10 guessDate 很给力!!!

查看全部评分

您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP