Basic pattern matching is not the best solution to this situation, but I'll focus on correct pattern matching.
See Programming Perl, Chapter 3, "The Range Operator" (pg 103 in the third edition).
'..' is a boolean operator, which is false by default. Once the left operator returns true, the '..' evaluates to true until the right operator evaluates to true.
As soon as the left operator evaluates to true, stating that the beginning of the range has been reached, the right operator is tested, to see if the end of the active reagion has been reached. That's why you don't get the regions betwween header lines, with '..': as soon as you detect the beginning of the region, it also triggers the end of region.
With '...', end of region is not tested when the start has just been detected, so you do get the regions between the header lines. But since the start and end patterns are the same, and the patterns match several times, you only get some of the regions.
Your file has the structure:
You want to begin printing at header section 3, the first QueueManager. You want to process key/value pairs until you are no longer in a QueueManager section.
Detect the beginning is fine the way you have it. The end of the region you want is marked by encountering a header line which is not a QueueManager header. (Or, of course, end of file) So a simple pattern you want is:
print if /^QueueManager:/ ... (/:/ && ! /^QueueManager:/);
i.e.: Begin printing when you encounter a QueueManager, and continue until you reach a non-QueueManager header line. But this is clumsy and relatively complicated. You COULD be daring and use a closing condition like /^^Q\w*:/, a header line which does not begin with a Q, but what if there's a QueryManager: header line? What you really want is a header line which is not a QueueManager header line. A negative look-behind assertion is perfect for this:
print if /^QueueManager:/ ... /^(?<=:QueueManager):/;
The closing condition is a ':' which follows any string ... any string other than 'QueueManager'.
As a minor style difference, I don't bother matching the '\*$' after the colon.
I typed "negative look-behind assertion", but then in the code I made a typo and used a positive look behind assertion. The code should be /^(?<!:QueueManager):/ ... BUT either a negative or positive look-behind assertion work. How did that happen? TomIn reply to Re: parsing a config file
by TomDLux
in thread parsing a config file
by Gorio3721
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |