Beefy Boxes and Bandwidth Generously Provided by pair Networks
Do you know where your variables are?
 
PerlMonks  

Re: Matching over multiple lines in a scalar

by chromatic (Archbishop)
on Oct 27, 2002 at 22:48 UTC ( #208394=note: print w/replies, xml ) Need Help??


in reply to Matching over multiple lines in a scalar

Why use negative-width assertions, when you're already using the /m flag? I like this:

use Data::Dumper; my $info = do { local $/; <DATA> }; my %lines; while($info =~ m/(\d+)\: (.+?)$/gm) { $lines{$1} = $2; } print Dumper (\%lines);

Of course, this also has an appeal:

my %lines = $info =~ /(\d+): (.+?)$/gm;

Passing a reference to Dumper allows Data::Dumper to dump the entire data structure without listifying it first.

Update: I miscopied the test data. Oops. Negative-width assertions are the way to go. :)

Replies are listed 'Best First'.
Re: Re: Matching over multiple lines in a scalar
by thpfft (Chaplain) on Oct 27, 2002 at 23:18 UTC

    Why use negative-width assertions, when you're already using the /m flag?

    To catch the broken lines. Yours is a very elegant construction, which I intend to steal, but I don't think that snippet meets the original requirements as it is. if you knew the tags wouldn't contain numerals, which I doubt, you could change it to:

    my $info = do { local $/; <DATA> }; my %lines = $info =~ /(\d+): ([^\d]+)/gs;

    but otherwise I can't see an alternative to the (?:^|\n).

    btw, is there any way to catch the matched values during a split? it would make this nice and tidy.

    update: damnation. redundant again.

    another update: I couldn't resist shrinking gjb's cheaper version and introducing a useful but quite unrequested array reference:

    my ($key, %data); for (<DATA>) { /^(?:(\d+):\s*)*(.+)$/; push @{ $data{ $key = $1 || $key } }, $2; }

      Take it one step further still and do away with the temporary scalar. This works.

      my %lines = do{local$/; <DATA> = ~m/(?:^|\n)(\d+)\:(.+?)(?=(?:\n\d)|$) +/gs };

      Now I'll wait for sauoq to reduce the regex to 3 chars and a twiddle and we've got a golf solution.:^)


      Nah! Your thinking of Simon Templar, originally played by Roger Moore and later by Ian Ogilvy

        after a tactful /msg from chromatic, i can confirm that this works too, provided the data are very tidy indeed.

        (i wish someone would redefine data as the mass noun it surely is, then I could stop pedantically pluralising around it.)

        my (undef, %lines) = split(/(\d+): /, join('', <DATA>));

        ugly, fragile and unwise, but you know, short.

Re: Re: Matching over multiple lines in a scalar
by BrowserUk (Pope) on Oct 27, 2002 at 22:58 UTC

    That doesn't work for the first and last 'lines' which actually each consist of 2 lines.


    Nah! Your thinking of Simon Templar, originally played by Roger Moore and later by Ian Ogilvy

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://208394]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others avoiding work at the Monastery: (3)
As of 2021-05-08 10:22 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    Perl 7 will be out ...





    Results (96 votes). Check out past polls.

    Notices?