查询删除所有非数字但仅保留最后一个句点/点

时间:2017-03-09 18:52:18

标签: sql regex oracle

设法使用正则表达式来过滤从varchar2number的字段值,以便它可以删除所有非数字并且只留下字符串中的最后一个句点,以便

"about 1,000.00" return 1000.00 or 1000
"3,000,000.000" return 300000.000 or 3000000
"3.000.000.000" return return 3000000.000 or 3000000
"a^*3^%*(C4.5d*9" return 34.59

任何方法只需将字符串更改为可由to_number()

转换的准确可转换字符串

我用

SELECT REGEXP_REPLACE(field_value, '[^0-9\.]+', '') from dual;

但无法解决第三种情况......

3 个答案:

答案 0 :(得分:2)

因为oracle中的正则表达式有些限制我不认为它只能使用regexp_replace。你可以这样做一个解决方法:

SELECT
  CASE
    WHEN last_dot < 2 THEN digits_and_dots
    ELSE REPLACE(SUBSTR(digits_and_dots, 1, last_dot - 1), '.') ||
                 SUBSTR(digits_and_dots, last_dot)
  END
FROM (
  SELECT
    INSTR(digits_and_dots, '.', -1) last_dot,
    digits_and_dots
  FROM (
    SELECT
      REGEXP_REPLACE(field_value, '[^0-9\.]+', '') digits_and_dots
    FROM DUAL
  ) t
) o

答案 1 :(得分:1)

这是一种方法,假设有一个十进制字符。你正在使用的值是一个字符串,所以我想到我们想要保留的小数作为字符串的分隔符,并根据它将其分成两部分。第一部分是所有字符,但不包括最后一个小数,第二部分是最后一个小数,后面是所有字符。然后应用替换,删除第一部分中不是数字的所有内容,以及第二部分中不是数字或小数的所有内容,然后将它们连接在一起。需要更多测试与不同的输入,但你明白了。所有这些正则表达式都很昂贵,所以我怀疑这将是最快的解决方案。

with tbl(str) as (
  select 'about 1,000.00'  from dual union
  select '3,000,000.000'   from dual union
  select '3.000.000.000'   from dual union
  select 'a^*3^%*(C4.5d*9' from dual
)
select str original,
       regexp_replace(regexp_substr(str, '^(.*)\.', 1, 1, NULL, 1), '[^0-9]+', '') ||
       regexp_replace(regexp_substr(str, '.*(\..*)$', 1, 1, NULL, 1), '[^0-9\.]+', '') Converted
from tbl;

SQL> /

ORIGINAL        CONVERTED
--------------- ---------------
3,000,000.000   3000000.000
3.000.000.000   3000000.000
a^*3^%*(C4.5d*9 34.59
about 1,000.00  1000.00

SQL>

答案 2 :(得分:0)

最短路径如下:

select regexp_substr('a^*3^%*(C4.5d*9s','\d+\.\d+') from dual;

select regexp_replace('a^*3^%*(C4.5d*9s', '[^0.0-9]', '') from dual;