Beefy Boxes and Bandwidth Generously Provided by pair Networks
Think about Loose Coupling
 
PerlMonks  

grab 2 blocks of texts from file

by Anonymous Monk
on Apr 12, 2012 at 14:09 UTC ( [id://964764]=perlquestion: print w/replies, xml ) Need Help??

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

Hi perl geniuses :p I'm trying to grab 2 "sections" of text from a file, i use a marker to tell the program where to begin and end at each section.. here is my attempt.
@text1 = (); @Section = split("\n", $filedata); foreach (@Section) { if (/^#begin/ .. /^#end/) { $eval .= "$_\n"; } if (/^#begin2/ .. /^#end2/) { push(@text1, $_); } } @arrBlock = (); for ($x=1;$x<@text1-1;$x++) { push(@arrBlock,$text1[$x]); } this seems valid, i can print $arryBlock[index] but i cant do a foreac +h loop through it? here is an example file: #begin aaa bbb ccc ddd #end #begin2 xxx ccc bbb #end2
now text1 contains the first block of content and arrblock contains the second.. i know i suck at variable names heh

Replies are listed 'Best First'.
Re: grab 2 blocks of texts from file
by temporal (Pilgrim) on Apr 12, 2012 at 15:21 UTC

    Your code doesn't do what you've specified. Maybe you didn't post all of it?

    It builds a string into the $eval variable containing the first block of text from your file (including your markers).

    It then pushes the lines from the second block (including your markers) into @text1.

    Then it copies @text1 minus your markers over to @arrBlock.

    So in the end, @arrBlock contains your second block and @text1 contains your second block with the markers...

    It would probably be more efficient to do an array slice:

    @firstblock = @text1[1..($#text1-1)]; # remember the left index of the slice can never be greater than the r +ight... no -1

    Not sure what you mean by not being able to do a foreach loop through it:

    foreach $value (@arrBlock) { print "$value\n"; }
Re: grab 2 blocks of texts from file
by graff (Chancellor) on Apr 13, 2012 at 00:16 UTC
    Since you seem to be slurping the entire content of the data file into a scalar variable, it might be easier just to use regex matches on that one big string:
    if ( $filedata =~ /#begin\n (.*?) #end\n .*? #begin2\n (.*?) #end2/sx +) { ( $block1, $block2 ) = ( $1, $2 ); @arr_block1 = split /\n/, $block1; @arr_block2 = split /\n/, $block2; }
    Recall from your studies of perlre that the "s" modifier allows the "." wildcard to match new-lines as well as all other characters, and "x" allows for using spaces in the regex for legibility (not for matching literal spaces).

    I chose to match both blocks with one regex, but you could do each block as a separate regex match if you want.

Re: grab 2 blocks of texts from file
by Kenosis (Priest) on Apr 15, 2012 at 00:37 UTC

    I like graff's suggestion of using the s modifier in your regex if the file's slurped into $filedata. Given that, here's another solution to grabbing those two sections, and it then places them into an array of arrays @arrBlocks (where $arrBlocks[0] is an array of the first block's elements and $arrBlocks[1] is an array of the second block's elements):

    for($filedata =~ /#begin\d*?\n(.*?)#end\d*?\n/gs) { push @arrBlocks, [split "\n"]; }

    The regex matches your pattern and can be used for endless #begin/#end pairs that end with digits (e.g., #begin3/#end3, ...). If you started with #begin0/#end0, then $arrBlocks[0] would contain that block's elements.

    Hope this helps!

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://964764]
Front-paged by Corion
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others lurking in the Monastery: (5)
As of 2024-04-25 15:38 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found