http://qs321.pair.com?node_id=444625

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

Greetings Monks, This must be an extremely easy question to answer, but much searching has not yielded the answer I seek. I am parsing messages from TSM, which have a format like this:
ANE4954I Total number of objects backed up: 3
I need the "ANE4951I" part of the string, which can be found by simply applying the following regular expression: s/\s.*// However, I don't wish to change the original text, so I reasoned that as $a=+1 is equivalent to $a=$a+1, so $a=~s/\s.*// should be equivalent to $a = $a ~ s/\s.*//, enabling me to express my needs thus:
$message_id=$message ~ s/\s.*//;
Sadly, this gives me a syntax error. What is the correct syntax for this? For now, I have coded it like this:
$message_id=$message; $message_id=~s/\s.*//;
But I suspect there is a better way. Thanks,
Menno

Replies are listed 'Best First'.
Re: Applying a regular expression to a string
by ysth (Canon) on Apr 04, 2005 at 11:54 UTC
    =~ is not related to the ~ operator; the assignment variant of ~ would be ~=, except that ~ is a unary operator and so has no assignment variant.

    What you want is to select everything before the first \s, and assign that to $message_id; use a match, not a substitution, to do that:

    ($message_id) = $message =~ /^(\S*)/;
    (Note the parentheses around $message_id that make it a list assignment; you need to do the assignmentmatch in list context to have it return anything besides success/failure.)
      Simple and elegant. I will start using this construct as soon as I next come across this type of problem. Thank you all.
Re: Applying a regular expression to a string
by ambs (Pilgrim) on Apr 04, 2005 at 11:42 UTC
    If $a=+1 is not the same as $a=$a+1. This is just true in case $a is undef or zero. So, you might want to say $a+=1 is the same as $a=$a+1. In any case, $a=$a+1 changes $a, so that is not what you want.

    Your second code snipet is correct. You can also use

    ($message_id = $message)=~s/\s.*//;

    Alberto Simões

Re: Applying a regular expression to a string
by BazB (Priest) on Apr 04, 2005 at 11:46 UTC
    Try something like:
    my $message_id = $1 if $message =~ m/([\w\d]+)\s+.*/;

    If the information in this post is inaccurate, or just plain wrong, don't just downvote - please post explaining what's wrong.
    That way everyone learns.

      my $message_id = $1 if $message =~ m/([\w\d]+)\s+.*/;

      Putting my (a compile-time directive) with an if statement modifier (which can only take place at run-time) is confusing, and therefore deprecated.

      Also, there's no point at all in having .* at the end of the regexp: since one of the things it would happily match is nothing, it isn't making any restrictions at all about what can follow the \s+, so is just adding noise.

      Finally, the \w class already includes digits, so writing [\w\d] doesn't add anything.

      Here's how I might have written this:

      $message =~ /^(\w+)/ or die "Message '$message' doesn't start with an identifier.\n"; my $message_id = $1;

      die might not be the most appropriate thing to do here; adjust as appropriate. But if you're adamant that $message could never not match the pattern, then a die test is better than nothing: if you're right, then it'll never happen, and if you're wrong then your assumption was wrong so there's a problem elsewhere and at least you found out about it.

      Smylers

Re: Applying a regular expression to a string
by Zaxo (Archbishop) on Apr 04, 2005 at 11:45 UTC

    How about this?

    my $message_id = do { local $_ = $message; (split)[0]; };

    After Compline,
    Zaxo