Beefy Boxes and Bandwidth Generously Provided by pair Networks
"be consistent"
 
PerlMonks  

problem with multi-line

by Anonymous Monk
on Aug 25, 2000 at 16:25 UTC ( #29606=perlquestion: print w/replies, xml ) Need Help??

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

I have been trying to scan a file and perform an 'if' using a multi-line m option, but unfortunately i am unable to get the result I want. Here is the code I have written #!/usr/local/bin/perl -w # analyse_map.perl # Open map files (map_merc and rom.dld) open(MAP, "<map_merc") || die "Unable to open map_merc"; # Read map_merc : while(<MAP>) { if( ($titi, $toto) = /^\.(\w+).*$\t+\.\w+\W+(\w+).*$/m) { print($titi, $toto, "\n"); } } close(MAP); What I want to do is find a line that starts with a '.' and put the alphanumeric in the scalar $titi, than scan the next line to match the alphanumeric and put it in scalar $toto. But it is generating an error and cannot use it. This is just a rial code I wrote for the actual program, but as this part isn't functioning right I cannot add it to the other code. Thanking you for your help. S. Navalkar

Replies are listed 'Best First'.
Re: REPOST problem with multi-line
by cwest (Friar) on Aug 25, 2000 at 16:36 UTC
    I have been trying to scan a file and perform an 'if' using a multi-line m option, but unfortunately i am unable to get the result I want.

    Here is the code I have written

    #!/usr/local/bin/perl -w # analyse_map.perl # Open map files (map_merc and rom.dld) open(MAP, ") { if( ($titi, $toto) = /^\.(\w+).*$\t+\.\w+\W+(\w+).*$/m) { print($titi, $toto, "\n"); } } close(MAP);
    What I want to do is find a line that starts with a '.' and put the alphanumeric in the scalar $titi, than scan the next line to match the alphanumeric and put it in scalar $toto. But it is generating an error and cannot use it. This is just a rial code I wrote for the actual program, but as this part isn't functioning right I cannot add it to the other code. Thanking you for your help.

    S. Navalkar

    --
    Casey
    
      /^\.(\w+).*$\t+\.\w+\W+(\w+).*$/m
      So you're looking for something like this, I think:
      .somewords any amount of garbage till a suposed end of line [some number of tabs].nomatchwords matchedwords garbage to eol
      I'm going on this assumption since I have NO real example of your test data.
      #!/usr/local/bin/perl -w use strict; $|++; $/="\n."; while ( <DATA> ) { print join ' ', /^\.?(\w+).+\n\t+\.\w+\W+(\w+)/; print "\n"; } __DATA__ .this is a line .and this is another line .again, a line. .Yet another line
      I hope this helps.
      --
      Casey
      
      Can you give a piece of example-contents of the file you want to scan and the result you want? I don't completely understand what you're trying to do... Jouke Visser, Perl 'Adept'
Re: problem with multi-line
by tenatious (Beadle) on Aug 25, 2000 at 16:50 UTC
    There is a problem with the "match" statement.... you have

    $toto) = /

    it should be

    $toto) =~ /

    I don't know if that's the only problem, but that's one of them.

      I don't think that's the problem, he doesn't appear to be opening anything properly or reading anything from the filehandle.

      the ($titi, $toto) = m/$matchstuff/; puts the match operator in a list context, it then return a list of backreferences ($1, $2, ...). this means $titi is assigned the value of $1 and $toto is assigned the value of $2. Which is what our anonymous friend appears to be attempting.

      The "spec" is quite confused, I'm not sure what is needed in order to match the second line. Is there a manditory tab character at the start, the regex appears to say there is but that may just be using the wrong modifier. I'm going to assume that there is at least one tab, here's my take on the problem.

      #!/usr/local/bin/perl -w use strict; my ($titi, $tito); { $_ = <DATA>; if (m/^\.(\w+)/ .. m/^\t+\.\w+\W+(\w+)/) { $tito = $1 and next if defined $titi; $titi = $1 unless defined $titi; }; redo; } print "$titi, $tito\n"; __DATA__ .this is a line .and second is another line .again, a line. .Yet another line
      Don't forget that you need to properly open the file you will be reading from, I'm just using the DATA file handle here (as pinched from previous answer by ctweten :-)

      I suppose I should comment on what I've differently, I'm using two regexs and the range operator. The range operator in scalar context is a flip flop operator. it returns false until the first expression matches, then it continues to return true until the second regex matches. So we check each line until we get a match for the first one, the $titi is undefined so the first statement is skipped and $titi is assigned a value. The "bare block loop construct" is then "redone" until the second regex matches at which point the value is assigned to $tito and the whole loop exits.

      If I've misunderstood the format of your data, you may have to tweak the regexs.

      Update:
      I've just realised that my code only pulls one pair of values if you want all pairs that may exist in the file, then you could try:

      #!/usr/local/bin/perl -w use strict; my @arr; while (<DATA>) { push @arr, $1 if m/^\.(\w+)/ .. m/^\t+\.\w+\W+(\w+)/; }; print join " ", @arr; __DATA__ .this is a line .and second is another line .again, a line. .Yet another line
      Which leaves your results in @arr

      Nuance

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://29606]
Approved by root
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others browsing the Monastery: (2)
As of 2022-05-18 16:40 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    Do you prefer to work remotely?



    Results (71 votes). Check out past polls.

    Notices?