Strong and valid
Weekly challenge 287 — 16 September 2024
Week 287: 16 Sep 2024
You are given a string, $str
.
Write a script to find if it is a valid number.
Conditions for a valid number:
A decimal number is defined as an optional sign '-' or '+' followed by one of the following:
An exponent is defined as 'e' or 'E' followed by an integer number.
Example 1 Input: $str = "1" Output: true Example 2 Input: $str = "a" Output: false Example 3 Input: $str = "." Output: false Example 4 Input: $str = "1.2e4.2" Output: false Example 5 Input: $str = "-1." Output: true Example 6 Input: $str = "+1E-8" Output: true Example 7 Input: $str = ".44" Output: true
No doubt someone will come up with one regular expression that does all of that, but I'm not that clever.
I have a main regular expression that more or less does it, but is too generous in two ways:
Each of these is then dealt with in separate regexes.
#!/usr/bin/perl # Blog: http://ccgi.campbellsmiths.force9.co.uk/challenge use v5.26; # The Weekly Challenge - 2024-09-16 use utf8; # Week 287 - task 2 - Valid number use warnings; # Peter Campbell Smith binmode STDOUT, ':utf8'; my @tests; say qq[\nValid numbers:\n \$str Valid?\n ----- ------]; @tests = ('23', '-23', '+23', '34.1', '-34.1', '+34.1', '.7', '-.7', '23e0', '23e-1', '23E+2', '-23e10', '+34.5e-10'); valid_number($_) for @tests; say qq[\nInvalid numbers:\n \$str Valid?\n ----- ------]; @tests = ('two', '23-', '23.1.2', 'e', 'e1', '34e1.2', '34e++6', '.e5', '+.e5', '123E', '.', '.e6' ); valid_number($_) for @tests; sub valid_number { my ($str, $str2, $valid, $a, $b); $str = $_[0]; $valid = 0; # basic match $a------------ $b----- if (($a, $b) = $str =~ m|^([-+]?\d*\.?\d*)([Ee]?.*)$|) { # but if [Ee] is present it must be followed by optional sign and 1+ digits $valid = 1 if ($b eq '' or ($a ne '' and $b =~ m|^[Ee][-+]?\d+$|)); } # decimal point must be preceded or followed by a digit (or both) if ($valid and $str =~ m|\.|) { $valid = 0 unless ($str =~ m|\d\.| or $str =~ m|\.\d|); } printf("%10s %10s\n", $str, ('false', 'true')[$valid]); }
Valid numbers: $str Valid? ----- ------ 23 true -23 true +23 true 34.1 true -34.1 true +34.1 true .7 true -.7 true 23e0 true 23e-1 true 23E+2 true -23e10 true +34.5e-10 true Invalid numbers: $str Valid? ----- ------ two false 23- false 23.1.2 false e false e1 false 34e1.2 false 34e++6 false .e5 false +.e5 false 123E false . false .e6 false
Any content of this website which has been created by Peter Campbell Smith is in the public domain