What esteemed monks think is the best, most elegant, most Perlish way to replace several fragments of the file starting with the one pattern(marker) and ending with another pattern/marker.

NOTES:

  1. Both starting and ending markers for each fragment are guaranteed to be unique within the file.
  2. Both file and fragments are generally small enough to fit in memory
  3. Fragments that need to be replaced can not overlap, but can follow one another without gaps (closing marker of one fragment can immediately follow by the opening marker of another fragment)
  4. For simplicity, we can assume that the output can be simply printed. It is not necessary to have it as an array in memory.
  5. We can also assume that that the replacement fragments are __DATA__ files with the first line as the opening marker and the last line as the closing marker. But this is optional and any other arrangement will suit.

For example, in the example below, I want to replace fragment between markers AAAAAA and BBBBBB with the list ( 'f11','f12','f13') and the fragment between markers CCCCCC and DDDDDD with the list ("f21","f22").

aaa
aaa
AAAAAA
ccc
ddd
BBBBBB
111
222
333
CCCCCC
444
555
666
DDDDDD
777
888
999
Thanks in advance for any help.

Again I am talking here not about the run of the mill solution (have three parallel arrays, for example, startmarker and stopmarker with markers and two dimensional (array of lists) replacement_list with the replacement fragments, find first starting marker in the file, loop till the end marker, inject the corresponding replacement fragment into output stream via the inner loop, and so on), but about the best, most elegant, way to accomplish this task in Perl that fully utilizes capabilities of the language.

May be it is possible to adapt range operator to the task:

0] # cat test_range while( $text=<DATA> ){ print "$. $text"; if ( ($text=~/^AAAAAA/) .. ($text=~/^BBBBBB/ ) ){ if ($text=~/^AAAAA/){ print "========= Start of the fragment detected at $.\n"; } print "Still true at $.\n"; $end=$.; # Is this the only way to detect the end of the fragment +? } } print "========= End of the fragment detected at $end.\n"; __DATA__ aaa aaa AAAAAA ccc ddd BBBBBB 111 222 333 CCCCCC 444 555 666 DDDDDD 777 888 999

Which does allow to detect the start and end of the fragment and can be generalized to use multiple passes over the text to detect all fragments, but I am not sure that this is the optimal way. While this might serve as the base of the shortest solution to the problem, it is impossible to avoid multiple passes over the text.

[0] # perl test_range 1 aaa 2 aaa 3 AAAAAA ========= Start of the fragment detected at 3 Still true at 3 4 ccc Still true at 4 5 ddd Still true at 5 6 BBBBBB Still true at 6 7 111 8 222 9 333 10 CCCCCC 11 444 12 555 13 666 14 DDDDDD 15 777 16 888 17 999 ========= End of the fragment detected at 6.

I have only a very basic knowledge of this operator.


In reply to The best way to replace several fragments of the file starting with the one pattern(marker) and ending with another pattern/marker. by likbez

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.