0

Here is my program

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

my $pattern = 'a .. f';

I am looking for a way to get an array from this pattern. The one way which I thought is to use split this in to three and get the array as follows. But it seems that this is not a feasible solution as in future pattern will change. It may be something like 'a..f1..9' so the split may not work there OR I have to write more generalize code for it. So looking for a way to generate the array based on the input pattern provided.

2
  • Is the -w flag on line 1 necessary? Commented Feb 22, 2011 at 8:09
  • 1
    as erickb cryptically hints, the -w is unnecessary - use warnings is the preferred 'modern' way to turn on warnings. seeing '-w' is often a sign that it's old legacy code, or that the writer is following outdated books/tutorials Commented Feb 22, 2011 at 9:40

6 Answers 6

2

Maybe the Parse::Range module can help you.

Sign up to request clarification or add additional context in comments.

Comments

1

Try this, capture the anchor characters via regex:

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

if($pattern =~ /([a-f])\s*\.\.\s*([a-f])/) {
    @ar = ($1..$2);
}

2 Comments

Actually $pattern is a scalar variable coming as an argument. So changing it to @pattern might not be possible.
@user502937 - maybe you should post more code then, people can't help you properly if there are extra things that they should be aware of!
1

This needs input validation because it will probably break fairly easily on invalid patterns, but it fits your basic spec:

#!/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;
}   

Output:

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

Comments

1

single line regex double eval:

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

result:

a b c d e f

This will even work on:

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

result:

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

To convert this string to a list is left to the reader :)

Regards

rbo

Comments

0

You coud use eval and change a bit your pattern :

#!/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;
}

output:

$VAR1 = [
          'a',
          'b',
          'c',
          'd',
          'e',
          'f',
          2,
          3,
          4
        ];

Comments

0

Do you realise that perl supports that sort of syntax already? i.e., 1..5 gives you the array (1,2,3,4,5). a..f gives you the array (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

Actually this is basically what M42 is suggesting but he's not explicitly pointing out that perl supports syntax not unlike that. He's turning the string into the array using the eval.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.