在提取价格文本时,Postgresql regex分组+转换问题



在postgresql中,我试图在文本字段中返回一个格式化的价格值,但只有当文本字段值不包含其他多余的文本时。

例如,有了这三个文本值…

  • '出价超过58万美元'

  • "499000"
  • '现在$419,000 -过去$459,000'

我想返回…

  • '出价超过58万美元'

  • "499000美元"

  • '现在$419,000 -过去$459,000'

我一直试图使用regex来提取我的值,然后转换为十进制,然后格式化输出以获得我想要的值。例如…

SELECT
CASE WHEN COALESCE(SUBSTRING(btrim('499000'::text) FROM '(^($?[0-9,]*)(.[0-9]{2})?)$'),'') != '' 
THEN to_char(substring('499000' FROM '^(($?[0-9,]*)(.[0-9]{2})?)$')::decimal, 'FM$999,999,999'::text) 
ELSE '499000' 
END as testresult

当我将'499000'换成'Offers over $580,000'时,我会得到一个错误,因为regex仍然将其拾取为有效,然后试图将其转换为十进制。然而,我很难理解为什么第二个值传递正则表达式,因为我说字符串必须以选项美元符号+数字组合开始。我想。

谁能在这个问题上给我指出正确的方向吗?我看过许多其他的regex帖子,但没有一个能帮助我回答这个问题(如果它包含解决方案,很高兴被指向另一个帖子)。

谢谢!

这里有一个您可能觉得方便的正则表达式选项。如果有小数,它会保留小数,并使用PostgreSQL的本地货币格式:

with vals(val) as (values ('Offers over $580,000'::text), ('499000'), ('NOW $419,000 - WAS $459,000'), ('  $ -1.87857 '), (' - $1.87857 '))
select case when val ~ '^s*(-?s*$?|$?s*-?)[0-9,]+.[0-9]+s*$' then val::money::text 
            when val ~ '^s*(-?s*$?|$?s*-?)[0-9,]+s*$' then left(val::money::text, -3)
            else val end
from vals

最新更新