smartperl has asked for the wisdom of the Perl Monks concerning the following question:

Hi geeks, I need substring of an orinal string with a range as offset. I will explain. Say I have a range "11-29,39-72,99-100,103,107" in some part of program. I need to extract substring corresponding to theses ranges. If my strign ABCDEFGH........... so on, if need substring which strats at 11th position to 29th, then from 39h to 72nd, then the one at 103rd position and so. Is there any way to sort this out. any cpan module available? thanks in advance

Replies are listed 'Best First'.
Re: substring within range
by GrandFather (Saint) on Feb 04, 2015 at 05:38 UTC

    See if substr will do what you want.

    Perl is the programming world's equivalent of English
Re: substring within range
by Laurent_R (Canon) on Feb 04, 2015 at 07:37 UTC
    Surely, substr will do what you need, but you'll need to wrap it in a (while or other) loop to process the various ranges one after the other.

    Je suis Charlie.
Re: substring within range
by roboticus (Chancellor) on Feb 04, 2015 at 12:59 UTC

    smartperl:

    When I see a problem like this, I normally break it apart into steps. Then, if I can't immediately write down the solution to any of those steps, I break the steps down even further. Something like:

    my $spec="11-29,39-72,99-100,103,107"; my $input = "The quick red fox jumped over the lazy brown dog."; # break spec into set of offsets and lengths # for each offset and length... for (my $idx=0 .. $#specs) { my ($input, $offset) = # how did I store them? #...extract a substring... my $substring = substr($input, $offset, $length); #...then print the result print "<$substring> is substr(...,$offset,$length)\n"; }

    Ok, I handled the easy part. Now I break down each comment that doesn't have code. Keep doing that until everything is done.

    When you start out, you sometimes get a problem that seems complicated, but if you start breaking it down into subproblems, you often find that it's just a few trivial bits glued together.

    ...roboticus

    When your only tool is a hammer, all problems look like your thumb.

Re: substring within range
by i5513 (Pilgrim) on Feb 04, 2015 at 09:43 UTC

    This sound like a home work, you should show us what did you try before

    I hope you can understand next code, which do what do you want. See split,perlre, and substr if you need help reading it.
    #!/usr/bin/perl use strict; use warnings; my $range="0-2,6-10,13,15"; my $test="this is a test with more than 15 characters"; for my $r (split (",",$range)) { if ($r =~ /^(\d+)(-(\d+))?$/) { my $first=$1; my $length=1; if (defined ($3)) { $length=$3-$1+1; } print "$r - ", substr ($test, $first,$length),"\n"; } }
    Updated: For fun,see this example for use regex "...(..)..(..).." style (no substr needed). For "x" usage see Multiplicative Operators:
    #!/usr/bin/perl use strict; use warnings; my $range="0-2,6-10,13,15"; my @range=split(",",$range); my $test="this is a test with more than 15 characters"; my $last=0; my $regex=""; for (@range) { if (/^(\d+)(-(\d+))?$/) { my $first=$1; my $length=1; if ($last lt $first) { $regex.="."x($last-$first); } $last=$first; if (defined ($3)) { $length=$3-$1+1; $last=$3; } $regex.="(".("."x$length).")"; } } my @matches = $test =~ /$regex/; my $n=0; for (@matches) { print ++$n." ($range[$n-1]): \"" ."$_","\"\n"; }
Re: substring within range
by Laurent_R (Canon) on Feb 04, 2015 at 18:49 UTC
    Just for fun, using an array slice instead of a loop (quickly tested under the Perl debugger):
    main::(-e:1): 42 DB<1> $input = "The quick red fox jumped over the lazy brown dog."; DB<2> $spec = "3-6,9-13,17-20"; DB<3> $spec =~ s/\-/../g; DB<4> @in = split //, $input; DB<5> print "@in"; T h e q u i c k r e d f o x j u m p e d o v e r t h e l +a z y b r o w n d o g . DB<6> print @in[eval ($spec)]; qui red jum DB<7>
    Just 3 lines of code besides the initializations.

    Now, of course, since array subscripts start at 0, I am counting the letters from 0. If we need counting letters from 1, not 0, we can just add an empty element at the beginning of the array:

    DB<7> unshift @in, ""; DB<8> print @in[eval ($spec)]; e quk redx ju

    Je suis Charlie.
Re: substring within range
by smartperl (Initiate) on Feb 09, 2015 at 06:25 UTC

    Thank you geeks for your support. I could sort it out in a way similar to what i5513 demonstrated. Thank you all... Looking forward to extended support