Perl генерирующий массив на основе шаблона ввода - PullRequest
0 голосов
/ 22 февраля 2011

Вот моя программа

#!/usr/bin/perl -w
use strict;
use warnings;

my $pattern = 'a .. f';

Я ищу способ получить массив из этого шаблона.Один из способов, который я подумал, это использовать разбить это на три и получить массив следующим образом.Но похоже, что это нереальное решение, так как в будущем картина изменится.Это может быть что-то вроде «a..f1..9», поэтому разделение может не сработать, ИЛИ мне нужно написать более обобщенный код для него.Поэтому мы ищем способ генерировать массив на основе предоставленного шаблона ввода.

Ответы [ 6 ]

2 голосов
/ 22 февраля 2011

Может быть, модуль Parse :: Range может вам помочь.

1 голос
/ 22 февраля 2011

регулярное выражение в одной строке: двойной эквивалент:

$pattern =~ s/(\w)\s*\.\.\s*(\w)/"\"\@{['$1'..'$2']} \""/gee;

результат:

a b c d e f

Это будет работать даже на:

my $pattern = 'a .. f1 .. 8';

результат:

a b c d e f 1 2 3 4 5 6 7 8

Для преобразования этой строки в список оставлено читателю:)

С уважением

rbo

1 голос
/ 22 февраля 2011

Это требует проверки ввода, потому что он, вероятно, довольно легко сломается на недопустимых шаблонах, но соответствует вашей базовой спецификации:

#!/usr/bin/env perl

use strict;
use warnings;

my $pattern = 'a .. f';
print join(' ', make_arr($pattern)), "\n";

$pattern = 'a..f1..9';
print join(' ', make_arr($pattern)), "\n";

sub make_arr {
    my $pat = shift;
    my @arr;

    while ($pat =~ s/(\w)\s*\.\.\s*(\w)//) {
        push @arr, $1 .. $2;
    }

    return @arr;
}   

Вывод:

a b c d e f
a b c d e f 1 2 3 4 5 6 7 8 9
1 голос
/ 22 февраля 2011

Попробуйте, захватите якорные символы через регулярное выражение:

my $pattern = 'a .. f';
my @ar;

if($pattern =~ /([a-f])\s*\.\.\s*([a-f])/) {
    @ar = ($1..$2);
}
0 голосов
/ 22 февраля 2011

Вы понимаете, что Perl уже поддерживает такой синтаксис?то есть 1..5 дает вам массив (1,2,3,4,5).a..f дает вам массив (a, b, c, d, e, f).

print join (", ", a..f), "\n" # a, b, c, d, e, f
print join (", ", a..f, 1..3), "\n" # a, b, c, d, e, f, 1, 2, 3

На самом деле это в основном то, что предлагает M42, но он явно не указывает, что perl поддерживает синтаксис нев отличие от этого.Он превращает строку в массив, используя eval.

0 голосов
/ 22 февраля 2011

Вы можете использовать eval и немного изменить свой шаблон:

#!/usr/bin/perl
use strict;
use warnings;
use 5.10.1;
use Data::Dumper;

my $pattern = '"a" .. "f", 2 .. 4';
my @array = eval $pattern;
if ($@) {
    say "eval failed: $@";
} else {
    say Dumper \@array;
}

выход:

$VAR1 = [
          'a',
          'b',
          'c',
          'd',
          'e',
          'f',
          2,
          3,
          4
        ];
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...