Join the Stack Overflow Community
Stack Overflow is a community of 6.6 million programmers, just like you, helping each other.
Join them; it only takes a minute:
Sign up

I'm trying to execute this lines of code:

  my $test = 'test .15oz test';
  $test =~ /([\d]+)([\.]?[\d]+)*oz\b/;
  print("test=$1\n");

The output of this is:

  test=15

I want to catch that dot. What am I doing wrong? The best would be to catch 0.15 somehow, but for now I can't even get a dot.

Any help with getting 0.15 from regex would be appreciated, so:

0.15 -> 0.15

.15 -> 0.15

..15 -> 0.15

0.0.0.15 -> 0.15

000.15 -> 0.15

15 -> 15

I tried also:

$test =~ /([\d]+)(\.?[\d]+)*oz\b/;
$test =~ /([\d]+)([.]?[\d]+)*oz\b/;

but with no success. Still getting "15" :/

share|improve this question
2  
You shouldn't escape a dot with a backslash inside a character class. Only outside. So either \. or [.] (there are other flavors of regexes that might fail when presented with superfluous backslash escapes, so it's best to avoid it). Anyway, that's not the problem here. – blubberdiblub Jan 19 at 18:11
1  
The character classes themselves appear to be superfluous. – Don't Panic Jan 19 at 18:15
    
@blubberdiblub thanks for a suggestion, but it didn't work :( – Ish Thomas Jan 19 at 18:19
1  
Use $test =~ /(\d*\.?\d+)oz\b/; – Wiktor Stribiżew Jan 19 at 18:21
    
@WiktorStribiżew yeah! that worked, thanks! this should be an answer. Btw. I'm not sure why this q was downvoted – Ish Thomas Jan 19 at 18:31
up vote 1 down vote accepted

You are using the first capturing group. In your pattern, ([\d]+)([\.]?[\d]+)*oz\b, the first capturing group matches one or more digits. To capture the whole float or integer number before oz, use

$test =~ /(\d*\.?\d+)oz\b/;
          ^         ^

where \d*\.?\d+ will match 0+ digits, an optional dot (note it is escaped outside a character class) and 1+ digits.

share|improve this answer

The strings you want to match are matched by

(?:\d+(?:\.\d+)?|\.\d+)oz

(Wiktor Stribiżew posted something shorter, but far less efficient.)

So you want

if ( my ($match) = $test =~ /(\d+(?:\.\d+)?|\.\d+)oz/ ) {
   say $match;
}

You can't possibly match 0.15 if your input .15 or ..15. Simply fix up the string independently of the match.

$match = "0".$match if $match =~ /^\./;

Similarly, trimming leading zeros is best done outside of the match.

$match =~ s/^0+(?!\.)//;

All together, we get

if ( my ($match) = $test =~ /(\d+(?:\.\d+)?|\.\d+)oz/ ) {
   $match =~ s/^0+(?!\.)//;
   $match = "0".$match if $match =~ /^\./;
   say $match;
}
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.