首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Perl语言中3位点分隔数与>3位数和字母数字的比较

Perl语言中3位点分隔数与>3位数和字母数字的比较
EN

Stack Overflow用户
提问于 2022-02-04 17:08:04
回答 1查看 105关注 0票数 2

有人能在Perl中帮助执行下面的操作吗?

  1. 从文件(例如)读取一组数字或字符。2021.2.3.0 / 2.8.1 / 2021.3.1_alpha )。
  2. 将其与数字2.4.0进行比较。(总是相同的数字)如果是大的还是小的。
  3. 例:(2.4.0 < 2021.2.3.0) ->这是假的。所以什么都别做。
  4. 如果(2.4.0 > 2.3.0) -->真--那么就做一些操作吧。
  5. 对于带点分隔的3位数字,我们可以这样做。(实际上我们正在做)。
  6. 但是,如何比较数字和阿尔法数字,其中有超过3位数。

在这里,我需要经常与2.4.0进行比较。有谁能指导我如何在Perl中做到这一点呢?

我的现有代码如下:

代码语言:javascript
复制
use strict;
use warnings;
my $path_ice = $ARGV[0];
my $filename = ($#ARGV == 0) ?  $ARGV[0]."\\medc17_tools.ini" : $ARGV[1];
my $flag = 0;
my $buld_ver = "";
my @buld_very = "";
my $status = 55;
if (open(my $fh, '<:encoding(UTF-8)', $filename))
 {
 while (my $line = <$fh>)
   {
   chomp $line;
   if($line=~m/^PRJ_BUILD_NAME=mdgb/) {$flag = 1;}
   if($line=~m/^PRJ_BUILD_VERSION=/)
     {
     @buld_very = split('=',$line);
     $buld_ver = substr($buld_very[1], 0, 5);
     $buld_ver =~ tr/.//d;
     if ($buld_ver < 240 ) {$status = 44;}
     last;
     }
   }
} 
else {
      warn "Could not open file '$filename' $!";
    }
if ($flag == 1)
{
exit(1);
}
else
   {
   exit(0);
    }

这里我们是转换点分离成整数和比较。它适用于3位数值。但不知道如何处理字母数字和>3位数字分开的数字。

有什么帮助吗?

EN

回答 1

Stack Overflow用户

发布于 2022-02-04 17:41:21

对于同时包含数字和非数字字符串的版本,有一个工具是类别::版本

代码语言:javascript
复制
use Sort::Versions;

my @sorted versions = sort versioncmp qw( 2021.2.3.0  2.8.1  2021.3.1_alpha );

在非常古老的Perls (pre-5.6)中使用sort { versioncmp($a, $b) } LIST

或者单独比较

代码语言:javascript
复制
if (versioncmp('2.4.0', '2.4.0_a') == -1) { ... }  # first is "lesser"

标准是

..。这两个字符串被视为由句点或连字符分隔的子单元。每个子单元可以包含任意数量的数字组或非数字组.如果双方都比较数字组,则使用数字比较,否则使用ASCII排序。如果所有的比较都是相等的,拥有更多单位的组或子组将获胜。句点比连字符更紧密地将数字组绑定在一起。

上面的第一个示例(排序),打印时生成

代码语言:javascript
复制
2.8.1
2021.2.3.0
2021.3.1_alpha

但问题中的一个例子是

例:(2.4.0 < 2021.2.3.0) ->这是假的。所以什么都别做。

注释中已经明确指出,在像2021.2.3.0这样的版本字符串中,领先的2021是一年;然后将其馀的字符串与传统的格式(如2.4.0 )进行比较。

我的另一个假设是:不管其他版本如何,晚一年都是赢家,如果只有一个版本有一年,那么这个版本就更新了。

一个简单的子项就够了

代码语言:javascript
复制
use Sort::Versions qw(versioncmp);   # imported by default, too

sub cmp_versions {
    my ($v1, $v2) = @_; 
    #croak "Usage: ", (caller(0))[3], " version-string version-string" 
    #   if not $v1 or not $v2;

    # Extract and collect years (need 'undef' when no year)
    my @years = map { /^([0-9]{4})\./ // undef } $v1, $v2;

    # Larger year wins; if same, or both absent, compare versions
    if ($years[0] and $years[1]) { 
        return $years[0] <=> $years[1] || versioncmp($v1, $v2)
    }   
    elsif ($years[0]) { return  1 } 
    elsif ($years[1]) { return -1 } 
    else              { versioncmp($v1, $v2) }     
}

测试程序

代码语言:javascript
复制
use warnings;
use strict;
use feature 'say';

#sub cmp_versions { ... }    # From above

my ($v1, $v2) = @ARGV;
$v1 //= '2021.2.0';
$v2 //= '2021.2.0_b';  #--> -1 (the first one considered earlier)

say cmp_versions($v1, $v2);

如果对版本进行排序,可以使用相同的版本。

代码语言:javascript
复制
use warnings;
use strict;
use feature 'say';

use Sort::Versions;

sub sort_versions {    
    return sort {
        my $ya = $a =~ /^([0-9]{4})\./;
        my $yb = $b =~ /^([0-9]{4})\./;
    
        if ($ya and $yb) {
            $ya <=> $yb || versioncmp($a, $b)
        }
        elsif ($ya) {  1 }
        elsif ($yb) { -1 }
        else        { versioncmp($a, $b) }
    }
    @_;
}

my @versions = qw(2.4.0 2021.2 2.4.0.0 2022.1.1 2021.2_a 2.6);

say for sort_versions( @versions );

输出

代码语言:javascript
复制
2.4.0
2.4.0.0
2.6
2021.2
2021.2_a
2022.1.1

这符合所述或提到的标准,其中一些在评论中作了澄清。

至于其他可能的(未声明的)细节--库只能做这么多工作来理解任何给定的版本控制方案,或者猜测预期的比较标准。对于非常特殊的标准,要比较的字符串可能首先需要被预处理成更传统的方案,或者“棘手的”字符串可以手工比较。

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/70990227

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档