【问题标题】:Regex to remove "-" from the middle of a timestamp string in postgresql正则表达式从 postgresql 中的时间戳字符串中间删除“-”
【发布时间】:2014-12-09 15:16:54
【问题描述】:

我有一个表格,其中包含 hour 列的 timestamp 格式不正确:

        hour         
---------------------
 2014-12-06-01:44:35
 2014-12-06-01:44:35
 2014-12-06-01:44:35
 2014-12-06-01:44:35
 2014-12-06-01:44:35
 2014-12-06-01:44:35

我想在中间用' '替换-,所以它看起来像这样:

        hour         
---------------------
 2014-12-06 01:44:35
 2014-12-06 01:44:35
 2014-12-06 01:44:35
 2014-12-06 01:44:35
 2014-12-06 01:44:35
 2014-12-06 01:44:35

我试过了:

select regexp_replace(hour, '\d{4}-\d{2}-\d{2}(-)\d{2}:\d{2}:\d{2}', ' ')
from my_table;

但不幸的是,它没有任何区别。
我使用的是 Redshift,而不是 PostgreSQL。

【问题讨论】:

    标签: regex postgresql timestamp amazon-redshift


    【解决方案1】:

    在 postgresql 中创建 Regex 表达式时需要考虑一些事项。首先,您需要转义反斜杠。所以你需要\\,而不是\。其次,您可以通过使用 \n 在括号中捕获第 n 个组来引用捕获组。您可以在替换值中使用捕获组来引用原始字符串的部分内容。

    将所有这些放在一起,这就是您所需要的:

    regexp_replace('hour', '(\\d{4}-\\d{2}-\\d{2})-(\\d{2}:\\d{2}:\\d{2})', '\\1 \\2') 
    

    【讨论】:

      【解决方案2】:

      Redshift 中的有限选项

      regexp_replace(hour, '(^\\d{4}-\\d{2}-\\d{2})-(\\d{2}:\\d{2}:\\d{2}$)', '\\1 \\2') AS a
      regexp_replace(hour, '(^\\d{4}-\\d\\d-\\d\\d)-(\\d\\d:\\d\\d:\\d\\d)$', '\\1 \\2') AS b
      regexp_replace(hour, '(^[\\d-]{10})-([\\d:]+)$', '\\1 \\2')                        AS c
      left(hour,10) || ' ' ||  substring(hour FROM 12)                           AS e
      

      现代 Postgres (9.1+) 中的更多选项

      regexp_replace(hour, '(^\d{4}-\d{2}-\d{2})-(\d{2}:\d{2}:\d{2}$)', '\1 \2') AS a
      regexp_replace(hour, '(^\d{4}-\d\d-\d\d)-(\d\d:\d\d:\d\d)$', '\1 \2')      AS b
      regexp_replace(hour, '(^[\d-]{10})-([\d:]+)$', '\1 \2')                    AS c
      reverse(regexp_replace(reverse(hour), '-', ' '))                           AS d
      left(hour,10) || ' ' ||  right(hour, -11)                                  AS e
      overlay(hour placing ' ' from 11)                                          AS f
      to_timestamp(hour, 'YYYY-MM-DD-HH24:MI:SS')                                AS ts
      

      SQL Fiddle.

      按出现顺序从“限制性”到“廉价”。 ts 很特别。

      一个

      这就像currently accepted answer by @Zeki,在开头和结尾都加上了锚点^$,以使其更加不模糊并且可能更快。

      您希望 \d 的特殊含义为 class shorthand 用于数字。
      在 Postgres 中,不要使用 \\ 转义反斜杠 \。除非您使用早已过时的非默认设置 standard_conforming_strings = off 运行,否则这是不正确的。
      Redshift 卡在了一个旧的开发阶段,就是这样做的。除非用另一个反斜杠转义,否则反斜杠会被解释。

      b

      \d\d\d{2} 更短更便宜。

      c

      使用字符类进行简化:数字 + 连字符:[\d-] 和数字 + 冒号:[\d:]

      d

      由于regexp_replace()没有第4个参数'g'只替换第一个匹配,你可以reverse()字符串,替换第一个连字符和reverse()后面。
      在 Redshift 中不起作用,因为它使用 总是 替换所有出现的 simpler version of regexp_replace()

      e

      如果格式固定如图所示,只需取前 10 个字符、一个空格和字符串的其余部分。
      Redshift 使用不接受负参数的simpler versions of left() and right(),所以我用substring() 代替。

      f

      或者,更简单一点,只是 overlay() 第 11 个字符加一个空格。
      Not implemented in Redshift.

      ts

      与其他类型不同,to_timestamp() 返回正确的 timestamp with time zone 类型,而不是 text。您也可以将结果分配给timestamp without time zoneDetails.。如果你想转换你的字符串,到目前为止最好的选择。 Not implemented in Redshift.

      【讨论】:

      • 不幸的是,没有一个问题给了我正确的答案。前 3 个(abc)根本没有改变结果。 4'th (d) - 删除了所有的-,所以时间戳看起来像这样2014 12 06 01:44:35。第 5 次 (e) 返回错误 context: Negative value given!。最后一个(f)返回,它不存在:function pg_catalog.overlay(character varying, "unknown", integer) does not exist
      • @Vor:嗯,抱歉,Redshift 有更多限制。正如您在小提琴中看到的那样,这一切都适用于现代 Postgres。我为 Redshift 和解释添加了一些工作版本。
      • 非常感谢您的详细解答
      【解决方案3】:
      (\d{4}-\d{2}-\d{2})-(\d{2}:\d{2}:\d{2})
      

      试试这个。替换为$1 $2。查看演示。

      https://regex101.com/r/iY3eK8/13

      【讨论】:

      • 他们的输出正是我想要的。但是你能指导我在我的 sql 命令中改变什么(在正则表达式部分旁边)
      • @Vor 在正则表达式旁边更改替换字符串。$1 $2\1 \2
      • 我尝试过regexp_replace(hour, '(\d{4}-\d{2}-\d{2})-(\d{2}:\d{2}:\d{2})', '\1 \2')regexp_replace(hour, '(\d{4}-\d{2}-\d{2})-(\d{2}:\d{2}:\d{2})', '$1 $2'),但仍然没有给我正确的结果。
      • 非常感谢您的帮助,您的回答是正确的,但就像@Zeki 建议的那样,我不得不转义它的反斜杠。
      猜你喜欢
      • 2016-08-03
      • 1970-01-01
      • 1970-01-01
      • 2013-04-16
      • 2016-08-31
      • 1970-01-01
      • 1970-01-01
      • 2021-01-17
      • 2014-06-20
      相关资源
      最近更新 更多