Perl multiline regex only returns first match

Posted on 2007-08-02
Last Modified: 2012-05-05
I'm trying to do a multiline regex on a file and print out ALL matching entries, however only the first one is being returned.
I'm sure I'm missing something obvious/fundamental.

Here is a sample of the file contents, showing 2 entries that should be returned:

    RECORD   : T011                                                                                                                  
    TRANSACTION TYPE : 010 REFERRENCE NUMBER : 14110207300000000823302  
    TRANSACTION AMT : 00000010000M    /OP0            
          NO.01 ITEM           : RECORD TYPE                                                                                        
                CODE & MESSAGE : 0301 TRAILER RECORD DOES NOT EXIST.                                                                
                CONTENTS       :                                                                                                    
    LICENSEE ID(HEADER) : 141102                                                    CENTRAL PROC DATE  : 07/31/2007                  
    PROCESSING DATE     : 07/30/2007       SEQUENCE NUMBER : 002                    VERIFICATION TIME  : 07/31/2007                  
    CURRENCY  : P00                                                                    (START -  END)  : 05:02:45 - 05:02:52        
                                              TOTAL COUNT   :      1           TOTAL AMOUNT   :                0.000                
                                                  PROCESSED COUNT :      0           PROCESSED AMOUNT :                0.000        
                                                  ERRONEOUS COUNT :      1           ERRONEOUS AMOUNT :                0.000        
    RECORD   : 0110                                                                                                                  
    TRANSACTION TYPE : 107 REFERRENCE NUMBER : 41102073000000008233221  
    TRANSACTION AMT : 0000010000MO    /P00            
          NO.01 ITEM           : RECORD TYPE                                                                                        
                CODE & MESSAGE : 0301 TRAILER RECORD DOES NOT EXIST.                                                                
                CONTENTS       :                                                                                                    

Here is the relevant code snip as it is currently:

      local $/ = undef;
      open (FH, "<", $v_filename_full)
        or die "Could not open file ($v_filename_full): $!";
      while (<FH>)
        print "$1,R,$2,$3" if (/.*REFER+ENCE\sNUMBER\s:\s([\d]{23}).*CODE\s&\sMESSAGE\s:\s(\d+)\s(.*\.)/sg);

The output I'm after would be:
14110207300000000823302,R,0301,TRAILER RECORD DOES NOT EXIST.                                                                
41102073000000008233221,R,0301,TRAILER RECORD DOES NOT EXIST.                                                                

But only the first line is being returned:
14110207300000000823302,R,0301,TRAILER RECORD DOES NOT EXIST.                                                                

Thanks in advance.
Question by:troesler
    LVL 27

    Assisted Solution

    This modification seemed to work for me:
           print "$1,R,$2,$3" if (/.*?REFER+ENCE\sNUMBER\s:\s([\d]{23}).*?CODE\s&\sMESSAGE\s:\s(\d+)\s(.*?\.)/sg);
    LVL 39

    Accepted Solution

    The while loop should not loop on <FH> because with $/ set to undef, you will read the entire file at once.  Also, the regex has a few bugs in it.  Try like this:

    local $/ = undef;
    open (FH, "<", $v_filename_full) or die "Could not open file ($v_filename_full): $!";
    print "$1,R,$2,$3\n" while (/REFER+ENCE\sNUMBER\s:\s([\d]{23}).*?CODE\s&\sMESSAGE\s:\s(\d+)\s(.*?\.)/sg)
    LVL 27

    Expert Comment

    Thanks for the question and the points.

    Author Comment

    Thanks Guys - I used Adam314's solution and it is working as expected.

    Write Comment

    Please enter a first name

    Please enter a last name

    We will never share this with anyone.

    Featured Post

    How to improve team productivity

    Quip adds documents, spreadsheets, and tasklists to your Slack experience
    - Elevate ideas to Quip docs
    - Share Quip docs in Slack
    - Get notified of changes to your docs
    - Available on iOS/Android/Desktop/Web
    - Online/Offline

    Suggested Solutions

    As most anyone who uses or has come across them can attest to, regular expressions (regex) are a complicated bit of magic. Packed so succinctly within their cryptic syntax lies a great deal of power. It's not the "take over the world" kind of power,…
    In the distant past (last year) I hacked together a little toy that would allow a couple of Manager types to query, preview, and extract data from a number of MongoDB instances, to their tool of choice: Excel (…
    Learn how to match and substitute tagged data using PHP regular expressions. Demonstrated on Windows 7, but also applies to other operating systems. Demonstrated technique applies to PHP (all versions) and Firefox, but very similar techniques will w…
    Explain concepts important to validation of email addresses with regular expressions. Applies to most languages/tools that uses regular expressions. Consider email address RFCs: Look at HTML5 form input element (with type=email) regex pattern: T…

    758 members asked questions and received personalized solutions in the past 7 days.

    Join the community of 500,000 technology professionals and ask your questions.

    Join & Ask a Question

    Need Help in Real-Time?

    Connect with top rated Experts

    13 Experts available now in Live!

    Get 1:1 Help Now