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

Ok, so I searched the archives but I still don't get it. I have the following text in a file that I want to match:

Total Datafile Size MB
----------------------
73602.1406


Total Database Size MB
----------------------
48107.7656


Total Free Space MB
-------------------
25462.8125

The code I tried to match the following:

Total Datafile Size MB
----------------------
73602.1406

is (and many variations at which point I gave up):
local $/; # slurp the entire file local *FH; open (FH, $file_name) or die "Cannot open"; my $text = <FH> if ($text =~ /[^Total Datafile Size MB\s*][^-{22}]/s) { print "Matched\n"; }
My ultimate goal is to match this:

Total Free Space MB
-------------------
25462.8125

and then grab the number 25462.8125.

Any ideas?

many thanks

mohammed

Edited by Chady -- Added code tags.

Replies are listed 'Best First'.
Re: Matching Across Lines
by duff (Parson) on Feb 24, 2004 at 22:12 UTC

    You need to use the /m modifier so that ^ can match the start of lines within your string. Otherwise it just matches the start of your string and not lines within it. Also, you might want to use the /x modifier so that you can comment your RE a little bit. Here's a snippet for you to modify as is your wont:

    #!/usr/bin/perl -l $text = do { local $/; <DATA> }; print $1 if $text =~ / ^Total\s+Datafile\s+Size\s+MB\s* # header ^-+\s* # separator ^([\d.]+) # the number I want /mix; __DATA__ Total Datafile Size MB ---------------------- 73602.1406 Total Database Size MB ---------------------- 48107.7656 Total Free Space MB ------------------- 25462.8125
    Update: Some other notes. I'm not sure why you're using local *FH; but if you have a modern perl, you can do something like this instead:

    open(my $fh, $file_name) or die; my $text = do { local $/; <$fh> }; # slurp close $fh;
      matija and duff
      Many thanks for your replies. I got it working using duff's
      solution. The local *FH stuff I think I picked out from Programming
      Perl or some where on the net. Not sure.

      Anyway, I changed it as described in the solution.

      One thing I'm still confused about are the m and s modifiers.

      Still don't understand:
      /m matches ^$ next to embedded \n
      -- not sure what this means

      /s . match newline and ignores deprecated $*
      -- same here, not sure what this means

      Anyway, thanks both for replying and getting my script
      working!!!
        OK, ok, ok...I understand now....
        I re-read http://www.infocopter.com/perl_corner/perlre.htm
        and http://lists.w3.org/Archives/Public/public-qt-comments/2003Jul/0091.html

        I also got both solutions working. Here is majita's
        solution which I just figured out:

        if ($text =~ /^Total Datafile Size MB(-+)\s+(\d.+)/s) {
        print $2;
        }

        Again, thanks both for helping me out.

        mohammed
Re: Matching Across Lines
by mkb125 (Initiate) on Feb 24, 2004 at 21:38 UTC
    Ok, wait
    I re-read the archs again. I changed my regexp to

    if ($text =~ /[^Total Datafile Size MB\s*\n(.*)^-{22}]/s)
    Seems to be working (I think)

    Now all I need is to match for the number on the 3rd
    line and grab it.

    mohammed
      To do that, the regexp should be
      if ($text =~ /^Total Datafile Size MB\s*\n(.*)^-{22}\s*\n(\d+\.\d+)/s)
      The second number will now be in $2.

      While you're at it, you should also change the .* in the first paren with something like \d+\.\d+.

      I realize both work right now, but if you get some funny stuff in your file, the stricter version will make sure you don't pick up a non-number.