in reply to Best practice validating numerics with regex?
I note that each of your test strings has either a single valid number, or a single invalid sequence of digits and dots. What should be the result of, eg, '12.34 and 56.78', or '12.34 on 2004.04.12' or 'on 2004.04.12 found 12.34'?
Your question is also a little unclear in that you ask that the answer be "efficiently" achieved; but "efficient" is a relative term - what counts as "efficient enough"? (Is there a maximum length of strings that must be parsed within whatever limits you set?)
As far as I remember the CUT operator /(?>...)/ is not implemented in a hugely efficient manner, but it may well be sufficient for your needs. You might use that something like:
m{ ^ [^-+\d.]* (?> ( (?# cut and capture) [-+]? (?: \.\d+ | \d+ (?: \. \d* )? ) ) ) (?!\.) }x
This (giving the result in $1) appears to pass your existing tests, and finds "12.34" for my first two additional cases and no match for the third.
Update: on second thoughts, the cut should not be necessary, just need to expand the tailing negative lookahead:
m{ ^ [^-+\d.]* ( [-+]? (?: \.\d+ | \d+ (?: \. \d* )? ) ) (?![.\d]) }x
Note also that the efficiency of CUT is suboptimal mainly when it is being hit repeatedly (eg as part of an alternation in a larger pattern), so it should be fine in this case anyway.
Hugo
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re^2: Best practice validating numerics with regex?
by Anonymous Monk on Oct 16, 2023 at 23:52 UTC | |
by hv (Prior) on Oct 17, 2023 at 02:38 UTC | |
by NERDVANA (Priest) on Oct 17, 2023 at 00:26 UTC | |
by perlboy_emeritus (Scribe) on Oct 17, 2023 at 00:12 UTC | |
by eyepopslikeamosquito (Archbishop) on Oct 17, 2023 at 11:38 UTC |