8

I'm playing around with Perl and trying to get a better understanding of its substring/regex functionality.

Say I have a string such as

[48:31.8] Sent: >33*1311875297587*eval*0*frame[0]*"A"<

and want to return 1311875297587. It will always be in that format. How would I do this using Perl?

Thanks

1
  • 1
    Describe how you identify the part of interest. String of digits at least 3 digits long? Start with 4th character following ">"? digits before "*eval"? etc... Commented Aug 1, 2011 at 21:04

4 Answers 4

17

Assuming that "[48:31.8]..." is in $string, then:

my ($number) = $string =~ /\*(\d+)\*eval\*/;

$number will be undefined if the string doesn't match, otherwise it will contain the digits between "*" and "*eval*".

Sign up to request clarification or add additional context in comments.

3 Comments

I'd split that input on * and parse it based on the substring number. Less of a hack, more robust.
Just found this 14 years later! Thanks! I don't understand why putting the variable name in brackets makes it work though..? Otherwise without, it just says "1" (I assume: for success).
@Aaron Perl has the feature that functions and operators can tell if their caller is expecting a single value ("scalar context") or multiple values ("list context"), and may return different results depending on which is the case. The matching operator =~ does this; it returns a simple boolean success code in scalar context, or a list of matching subgroups in list context. The assignment operator provides a scalar context to its right-hand side if assigning to a single scalar variable, and a list context otherwise. Wrapping a single variable in parentheses makes it a single-element list.
4
if ($str =~ /\*(\d+)\*/ ) {
    print $1;
}

Comments

1
my ($num) = '>33*1311875297587*eval*0*frame[0]*"A"<' =~ /(\d{3,})/;
print $num;

Comments

0

For what it's worth, I think this is a more robust answer:

while(<STDIN>)
{
    @fields = split(/\*/,$1) if(/(?<=>)([^<>])+(?><)/);
    print "$fields[1]\n";
}

This allows access to all of your fields if you need them, and doesn't rely on inherent order to parse out a particular field.

Replace the while loop with whatever line-by-line iteration you want. For testing though, run this as a Perl script, then paste in your line [48:31.8] Sent: >33*1311875297587*eval*0*frame[0]*"A"< or whatever else.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.