Perl:比较字符串中的数字

时间:2012-06-14 11:27:53

标签: string perl

给出以下输入:

A | 11 162 60 90 - 141 184

乙| 231 322 - 306 305 285 350

对于A,我想检查141是否介于(11,162)OR(60,90)之间。 如果是,则打印“在A中,141位于(11,162)之间。”

然后,我想检查184是否介于(11,162)OR(60,90)之间。 因为它没有,所以不需要打印。

同样,对于B,我需要打印介于(231,322)之间的数字。

我编写了以下Perl代码,但我没有得到正确的输出。

#!/usr/bin/perl -w
open LIST, "input.txt";
while($line=<LIST>)
{
@elem=split (/\|/,$line);
@nextone=split("--",$elem[1]);
@nextoneone = split(" ",$nextone[0]);
@nexttwo=split(" ",$nextone[1]);

if ($nexttwo[0] > $nextoneone[0] && $nexttwo[0] < $nextoneone[1])
{
print"$elem[0]\t $nexttwo[0]\t $nextoneone[0]\t $nextoneone[1]\n";
}
elsif ($nexttwo[0] > $nextoneone[2] && $nexttwo[0] < $nextoneone[3])
{
print"$elem[0]\t $nexttwo[0]\t $nextoneone[2]\t $nextoneone[3]\n";
}
elsif ($nexttwo[1] > $nextoneone[0] && $nexttwo[1] < $nextoneone[1])
{
print"$elem[0]\t $nexttwo[1]\t $nextoneone[0] \t$nextoneone[1]\n";
}
elsif ($nexttwo[1] > $nextoneone[2] && $nexttwo[1] < $nextoneone[3])
{
print"$elem[0]\t $nexttwo[1]\t $nextoneone[2] \t$nextoneone[3]\n";
}
}
   close (LIST);
   exit;

我不知道每行有多少元素。因此,我不知道如何实现一个循环进行比较。 任何关于如何改进代码的指导都将受到赞赏。

感谢您的帮助。

3 个答案:

答案 0 :(得分:1)

首先,我会改变你的脚本的一些事情。 1)使用严格 - 这意味着你抓住任何错别字

2)给变量更有意义的名字 - 我根据我所看到的改变了一些有意义但我不知道你的脚本是做什么的,所以你可能有更好的名字

3)输出一些调试,当你开发它时,你可以看到它正在做什么以及它为什么不起作用

你需要两个循环 - 一个循环遍历' - '左边的字符串部分中的值,一个循环遍历右边的条件。你想循环遍历外部循环中的值,然后每次都应该遍历内部循环中的所有条件。

    use strict;
    #!/usr/bin/perl -w
    open LIST, "input.txt";
    my $line;
    while($line=<LIST>) {
        my ($label, $content) =split (/\|/,$line);
        my ($conditionstring, $valuestring) =split("--",$content);
        my (@conditions) = split(" ",$conditionstring);
        my (@values) =split(" ",$valuestring);
        foreach my $this_val (@values) {
                my $matched_one_condition = 0;
                for (my  $f=0; $f< scalar(@conditions);$f+=2) {


                        print "Comparing $this_val to $conditions[$f] and to            $conditions[$f+1]\n";

                        if (($this_val > $conditions[$f]) && ($this_val < $conditions[$f+1])) {
                                $matched_one_condition= 1;

                        }
                }
                if ($matched_one_condition) {
                        print "$this_val\n";

                }
        }
}

注意 - 我已将调试行留在那里

答案 1 :(得分:0)

如果您不知道他们的号码,请在值上使用循环:

#!/usr/bin/perl
use warnings;
use strict;
use feature 'say';

while (<DATA>) {
    my ($header, $rangeS, $pointS) = /(.*)\|(.*) -- (.*)/;
    my @ranges = $rangeS =~ /([^ ]+ [^ ]+)/g;
    my @points = split / /, $pointS;

    for my $point (@points) {
        for my $range (@ranges) {
            my ($from, $to) = split / /, $range;
            if ($from <= $point and $point <= $to) {
                say "In $header, $point lies between ($from,$to)";
                last;   # Comment this line to get all the ranges for each point.
            }
        }
    }
}

__DATA__
A| 11 162 60 90 -- 141 184
B| 231 322 -- 306 305 285 350
C| 10 20 30 40 -- 1 2 3 4 5 6 7 8 9
D| 10 20 10 40 -- 1 10 20 40 10

答案 2 :(得分:0)

我对你的问题感到震惊。希望你能找到一些价值。我确实冒昧地对范围进行分类以处理B行的情况,例如: 306,305。

#!/bin/env perl
use strict;
use warnings;

while ( <DATA> ) {
    my @line = /\w+|\d+/g;
    my( $h, $ranges, $tests ) = (
        $line[0], [ [ sort @line[1,2] ], [ sort @line[3,4] ] ], [ @line[5,6] ]
    );
    map {
        my $test = $_;
        map {
            print "In $h, $test lies between (", join( ', ', @$_ ), ")\n"
                if grep { /^$test$/ } ( $_->[0] .. $_->[1] )
        } ( @$ranges )
    } @$tests
}

__DATA__
A| 11 162 60 90 -- 141 184
B| 231 322 -- 306 305 285 350