user1362796
user1362796

Reputation: 63

Need Regular expression - perl

I am looking for a regx for below expression:

my $text = "1170 KB/s (244475 bytes in 2.204s)";  # I want to retrieve last ‘2.204’ from this String.

$text =~ m/\d+[^\d*](\d+)/;   #Regexp

my $num = $1;

print " $num ";
Output:
204

But I need 2.204 as output, please correct me. Can any one help me out?

Upvotes: 0

Views: 60

Answers (3)

TLP
TLP

Reputation: 67900

The regex is doing exactly what you asked it to: It is matching digits \d+, followed by one non-digit or star [^\d*], followed by digits \d+. The only thing that matches that in your string is 204.

If you want a quick fix, you can just move the parentheses:

m/(\d+[^\d*]\d+)/

This would (with the above input) match what you want. A more exact way to put it would be:

m/(\d+\.\d+)/

Of course this will match any float precision number, so if you can have more of those, that's not a good idea. You can shore it up by using an anchor, like so:

m/(\d+\.\d+)s\)/

Where s\) forces the match to occur at only that place. Further strictures:

m/\(\d+\D+(\d+\.\d+)s\)/

You might also want to account for the possibility of your target number not being a float:

m/\(\d+\D+(\d+\.?\d*)s\)/

By using ? and * we allow for those parts not to match at all. This is not recommended to do unless you are using anchors. You can also replace everything in the capture group with [\d.]+.

If you are not fond of matching the parentheses, you can match the text:

m/bytes in ([\d.]+)s/

Upvotes: 4

Garry
Garry

Reputation: 109

Try this regex:

$text =~ m/\d+[^\d]*(\d+\.?\d*)s/;

That should match 1+ digits, a decimal point if there is one, 0 or more decimal places, and make sure it's followed by a "s".

Upvotes: 0

Patrick J. S.
Patrick J. S.

Reputation: 2935

I'd go with the second marker as indicator where you are in the string:

my ($num) = ($text =~ /(\d+\.\d+)s/);

with explanations:

/(    # start of matching group
 \d+  # first digits
 \.   # a literal '.', take \D if you want non-numbers
 \d+  # second digits
 )/x  # close the matching group and the regex

You had the matching groups wrong. Also the [^\d] is a bit excessive, generally you can negate some of the backspaced special classes (\d,\h, \s and \w) with their respective uppercase letter.

Upvotes: 0

Related Questions