代码之家  ›  专栏  ›  技术社区  ›  Stan Bridge

提取价格文本时postgresql regex分组+强制转换问题

  •  1
  • Stan Bridge  · 技术社区  · 10 年前

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

    例如,对于这三个文本值。。。

    • '出价超过580000美元'

    • '499000'

    • “现在419000美元-以前459000美元”

    我想回去。。。

    • '出价超过580000美元'

    • '$499,000'

    • “现在419000美元-以前459000美元”

    我一直在尝试使用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$580000”时,我得到了一个错误,因为regex仍然将其视为有效,然后尝试将其转换为十进制。然而,我很难理解为什么第二个值会传递regex,因为我的意思是字符串必须以选项美元符号+数字组合开头。我想。

    有人能给我指出正确的方向吗?我看到过许多其他的regex帖子,但没有一篇能帮助我回答这个问题(如果它包含解决方案,我很乐意再看一篇帖子)。

    谢谢

    1 回复  |  直到 10 年前
        1
  •  0
  •   Ezequiel Tolnay    10 年前

    这里有一个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