Както може би сте забелязали, методът, базиран на регулярни изрази, е почти невъзможно да се направи правилно. Например, вашият тест казва, че 1.234e-5
не е валидно число, когато наистина е така. Освен това сте пропуснали отрицателни числа. Ами ако нещо изглежда като число, но когато се опитате да го съхраните, ще доведе до препълване?
Вместо това бих препоръчал да създадете функция, която се опитва действително да прехвърли към NUMERIC
(или FLOAT
ако задачата ви го изисква) и връща TRUE
или FALSE
в зависимост от това дали това предаване е било успешно или не.
Този код напълно ще симулира функция ISNUMERIC()
:
CREATE OR REPLACE FUNCTION isnumeric(text) RETURNS BOOLEAN AS $$
DECLARE x NUMERIC;
BEGIN
x = $1::NUMERIC;
RETURN TRUE;
EXCEPTION WHEN others THEN
RETURN FALSE;
END;
$$
STRICT
LANGUAGE plpgsql IMMUTABLE;
Извикването на тази функция на вашите данни получава следните резултати:
WITH test(x) AS ( VALUES (''), ('.'), ('.0'), ('0.'), ('0'), ('1'), ('123'),
('123.456'), ('abc'), ('1..2'), ('1.2.3.4'), ('1x234'), ('1.234e-5'))
SELECT x, isnumeric(x) FROM test;
x | isnumeric
----------+-----------
| f
. | f
.0 | t
0. | t
0 | t
1 | t
123 | t
123.456 | t
abc | f
1..2 | f
1.2.3.4 | f
1x234 | f
1.234e-5 | t
(13 rows)
Не само че е по-правилно и по-лесно за четене, но и ще работи по-бързо, ако данните всъщност са число.