首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何将此语法解析为Perl中的数组?

如何将此语法解析为Perl中的数组?
EN

Stack Overflow用户
提问于 2010-09-21 19:43:36
回答 5查看 976关注 0票数 3

我有一个文件,其中包含使用以下语法的参数

代码语言:javascript
复制
RANGE {<value> | <value>-<value>} [ , ...]

其中value s是数字。

例如,所有这些都是有效的语法。

代码语言:javascript
复制
RANGE 34
RANGE 45, 234
RANGE 2-99
RANGE 3-7, 15, 16, 2, 54

如何将值解析为Perl中的数组?

例如,对于最后一个示例,我希望我的数组具有3, 4, 5, 6, 7, 15, 16, 2, 54。元素的排序并不重要。

最基本的方法是检查-符号以确定是否存在范围,使用循环解析范围,然后解析其余的元素。

代码语言:javascript
复制
my @arr;
my $fh, "<", "file.txt" or die (...);
while (<$fh>) {
    if ($_ =~ /RANGE/) {
        if ($_ =~ /-/) { # parse the range
            < how do I parse the lower and upper limits? >
            for($lower..$upper) {
                $arr[++$#arr] = $_;
            }
        } else { # parse the first value
            < how do I parse the first value? >
        }

        # parse the rest of the values after the comma
        < how do I parse the values after the comma? >
    }
}

  • I需要帮助解析数字。用于解析,我可以想到的一种方法是使用连续的拆分(在-,和)上。是否有更好的(干净和优雅,使用正则表达式?)方法?
  • 也欢迎您对整个项目结构提出意见/建议。
EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2010-09-21 19:58:44

我建议将行解析为一个单独的变量,因为$_往往会受到其他函数调用的打击。您可以同时使用chomp删除尾随换行符。

代码语言:javascript
复制
while (<$fh)>
{
    chomp (my $line = $_);
    # ...
}

接下来,您需要检测“范围”指示器,并提取后面的数字。如果没有这样的指示符,可以跳到下一行:

代码语言:javascript
复制
next if $line !~ /^RANGE (.*)$/;

现在,您可以开始提取数字,在逗号分隔符上拆分:

代码语言:javascript
复制
my @ranges = split /, /, $1;

现在,您可以提取破折号并将其转换为范围。这是一个棘手的部分--如果值中有一个破折号,那么获取第一个和第二个数字,然后用..操作符将它们转换成一个范围;否则,不要使用这个数字:

代码语言:javascript
复制
@ranges = map { /(\d+)-(\d+)/ ? ($1 .. $2) : $_ } @ranges;

把所有这些结合在一起,并结合表达,让我们:

代码语言:javascript
复制
my @numbers;
while (<$fh)>
{
    chomp (my $line = $_);
    next if $line !~ /^RANGE (.*)$/;

    push @numbers, map { /(\d+)-(\d+)/ ? ($1 .. $2) : $_ } (split /, /, $1);
}
票数 4
EN

Stack Overflow用户

发布于 2010-09-21 19:51:09

查看一下来自CPAN的Text::NumericList模块。它可以以类似的方式将字符串转换为数组:

代码语言:javascript
复制
use Text::NumericList;
my $list = Text::NumericList->new;

$list->set_string('1-3,5-7');
my @array = $list->get_array;     # Returns (1,2,3,5,6,7)

您至少可以查看它的源代码以获得想法。

票数 5
EN

Stack Overflow用户

发布于 2010-09-21 19:55:50

那这个呢?

首先将行拆分为由值分隔的元素,然后检查是否有“-”符号来创建范围:

代码语言:javascript
复制
if ($line =~ /RANGE ([\d\,\- ]+)/) {
    my $paramtxt = $1;
    my @elements = split(/\,/, $paramtxt);
    for my $element (@elements) {
        if ($element =~ /(\d+)\-(\d+)/) {
            $lower = $1;
            $upper = $2;
            push @arr, $lower .. $upper;
        } elsif ($element =~ /(\d+)/) {
            $solo = $1;
            push @arr, $solo;
        }
    } 
}
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/3763843

复制
相关文章

相似问题

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