Beefy Boxes and Bandwidth Generously Provided by pair Networks
Welcome to the Monastery
 
PerlMonks  

Parsing arguments with surrounding garbage.

by kschwab (Vicar)
on Apr 04, 2001 at 18:27 UTC ( [id://69674]=perlquestion: print w/replies, xml ) Need Help??

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

Monks, I have a short script that looks for commands and arguments buried within an email message. Since email sometimes inserts garbage (salutations, signatures, etc) before and after the message text, I need to find valid commands within the text.

I know the list of valid commands, and in this case, valid args are numeric. So, for the input "garbage validcommand 1234 221 garbage 999 213", I need to parse out the args "1234 221", and throw the rest out. The number of args can vary.

I've found something that works, but it seems inelegant:

$string="garbage validcommand 1234 221 garbage 999 213"; while ($string =~ s/validcommand\s+(\d+)/validcommand /) { push(@args,$1); }
Anyone have some better ideas ?

Replies are listed 'Best First'.
Re: Parsing arguments with surrounding garbage.
by Albannach (Monsignor) on Apr 04, 2001 at 18:47 UTC
    That doesn't look so inelegant to me, but here's a way that avoids the substitution, FWIW (though I'm sure someone can do better):
    $string = 'garbage validcommand 1234 221 garbage 999 213'; $string =~ m/validcommand\s+((\d+\s+)+)/; @args = split ' ',$1;

    --
    I'd like to be able to assign to an luser

Re: Parsing arguments with surrounding garbage.
by busunsl (Vicar) on Apr 04, 2001 at 18:49 UTC
    Don't use substitution here:
    $string="garbage validcommand 1234 221 garbage 999 213 validcommand 1 +2 34 garbage"; while ($string =~ /validcommand\s+((\d+\s+)+)/g) { push @args, split /\s+/, $1; }
Re: Parsing arguments with surrounding garbage.
by kilinrax (Deacon) on Apr 04, 2001 at 18:53 UTC
    Since you want "1234 221", not "1234", which is what that regex will capture, and you really want to be using match, not substitute, I'd suggest this:
    #!/usr/bin/perl -w use strict; my @args; my $string="garbage validcommand 1234 221 garbage 999 213"; while ($string =~ m!validcommand\s+(\d+(?:\s+\d+)*)!g) { push(@args, $1); } print @args;
      Thanks, I was looking for a match instead of a substitute, so this and the other replies were helpful.

      A note on your comment:

      Since you want "1234 221", not "1234", which is what that regex will capture

      The code I posted does work (because it takes n trips through the while() loop), and pulls in both 1234 and 221 into @args. It's just uglier than I wanted.

      Thanks all !

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others rifling through the Monastery: (4)
As of 2024-03-29 10:32 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found