Many thanks to "Wagner-David" for the code. I've slightly changed it, as below, but have still further questions.
use strict; my $counter = 1; my %Headinghash; my %Texthash; while (<DATA>) { chomp; if ( /^(\d+)\.\s+(.*)/ ) { $counter = $1; $Headinghash{$counter} = $2; }elsif ( ! /${counter}\./ ) { $Texthash{$counter} .= $_; }else { $counter = ''; } } foreach my $MyKey (sort {$a <=> $b} keys %Headinghash) { print "HEADING: $MyKey, $Headinghash{$MyKey}\n TEXT: $MyKey, $Texthash{$MyKey}\n"; } __DATA__ 1. This is a heading ........text in between ... 1.1. A subheading ... and this is text after subheading 1.1 1.2. Another subheading 2. Another heading ....... 3. Yet another heading ...... --- end code ----------------------------------------- This works fine for DATA as it is, but unfortunately my requirements are more specific. I would also like to use it for such data as: __DATA__ 1. This is a heading ........text in between ... 1. List item 1 2. List item 2 ..... more text in between 1.1. A subheading ... and this is text after subheading 1.1 1.2. Another subheading 2. Another heading ....... 3. Yet another heading ...... ---------- end data ----------------------- So checking on an initial digit is not specific enough, because in between a heading "$counter" and the next subheading "$counter.1", there might be a line beginning with "$counter" = a list entry. I really need to do a loop moving up a counter, *and* I need the search to be "position-aware". I guess my question boils down to: How to code "when there's a match of "1\.\s" in the beginning of a line, check whether there's a "1\.1\.\s" after the end of that line - if so, assign everything in between the end of that line and "1\.1\.\s." as a hash value, and move up the counter to 2; if not, move up the counter to 2 and search for a line beginning with "2\.\s" *after* "1\.1\.\s". " Birgit Kellner -- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]