user2052436
user2052436

Reputation: 4765

Perl regex to extract floating number

I need to modify someone's Perl script, and I am not familiar with Perl at all.

There is a scalar variable $var, whose value is a floating point number possibly followed by junk. I need to extract the floating point number.

The number is in non-exponential format: DDD[.DDD], and has no sign.

Fractional part may be missing. Integer part is not missing (.123 is just junk)

If the variable starts with junk (in particular, sign or decimal point), I need to extract empty string.

Examples:

-123.456 ==> ""
123. ==> "123"
123.456.789 ==> "123.456"
123.456junk ==> "123.456"
123junk ==> "123"
123.junk ==> "123"     # strip the dot if no fraction
.123 ==> ""
junk ==> ""
000.000 ==> "000.000"

Could someone provide a solution, I guess it should be: $var =~ s/REGEX_EXPRESSION, but I cannot figure out what REGEX_EXPRESSION should be.

Thank you.

Upvotes: 2

Views: 3453

Answers (3)

Paolo
Paolo

Reputation: 26014

Following your update, the expression you need is:

^\d+(?:\.\d+)?
  • ^\d+ Match digits at start of string.
  • (?: Start of non capturing group.
  • \.\d+ Match a literal ., followed by digits.
  • )? Close non capturing group making it optional.

Check the expression here.

A Perl example:

$var = "123.456.789";
print "old $var\n";
$var =~ /(^\d+(?:\.\d+)?)/;
print "new $1\n";

Prints:

old 123.456.789
new 123.456

Upvotes: 2

user2052436
user2052436

Reputation: 4765

So I am trying suggested expressions, I guess I am not using them correctly in Perl:

my $var = "123.456.66";
print "old $var\n";
$var =~ s/^\d+(?:\.\d+)?//;
print "new $var\n";

Output:

$perl main.pl
old 123.456.66
new .66

Upvotes: 0

Schwern
Schwern

Reputation: 164669

As I understand it, you need to extract the first one or two groups of digits from a string. Like so.

123.456.789  # 123.456
123.456abc   # 123.456
123abc       # 123
abc123       # nothing

The regex would look like this, expanded out for a better explanation.

qr{
  (
    \d+ 
    (?: \.\d+ )?
  )
}x;

qr is the regex quoting operator. Using x means to ignore spaces so things are more readable.

\d matches digits. + says to match 1 or more of the preceding. So \d+ is 1 or more digits.

() captures the contents.

(?:) groups the contents but does not capture.

? says to capture 0 or 1 of the preceding. It means it's optional.

So (?: \.\d+ )? means a dot followed by some digits is optional.

You'd use it like so.

my $str = "123.456abc";
my $digits_re = qr{ (\d+ (?: \.\d+ )?) }x;
my($digits) = $str =~ $digits_re;
print $digits;

For more information see the Perl Regex Tutorial and you can play with it on Regex 101.

Upvotes: -1

Related Questions