【问题标题】:substring a string with conditions用条件子串一个字符串
【发布时间】:2022-01-04 16:06:22
【问题描述】:

我有一列包含来自 tableXX 的值如下

file_name
my_String1_20220103_144415.csv
my_String2_20220106_155730.csv
my_String3_20220108_153930.csv
my_String4_20220103_144470.csv
my_String5_20220103_144415.csv

我的问题是如何在最后两个 '_' 后接一个点 '.' 后检索字符串。

有这样的输出

file_name
my_String1.csv
my_String2.csv
my_String3.csv
my_String4.csv
my_String5.csv

我试过这个查询:

select substring(file_name from '(.*)_') as file_name  from tableXX

【问题讨论】:

  • 您可以尝试使用 REGEXP_REPLACE 函数并将正则表达式(?:_[^_\r\n]+){2}\.匹配的子字符串替换为.

标签: regex postgresql


【解决方案1】:

你可以使用

select REGEXP_REPLACE(file_name, '^([^_]*_[^_]*).*(\.[^.]*)$', '\1\2') as file_name  from tableXX

^([^_]*_[^_]*).*(\.[^.]*)$ 正则表达式匹配

  • ^ - 字符串开头
  • ([^_]*_[^_]*) - 第 1 组(\1 指替换模式中的此组值):除__ 之外的任何零个或多个字符,以及零个或多个非_s
  • .* - 尽可能多的零个或多个字符
  • (\.[^.]*) - 第 2 组(\2 指替换模式中的此组值):一个 . 字符,然后是 . 字符以外的零个或多个字符
  • $ - 字符串结束

这是一个测试:

CREATE TABLE tableXX
    (file_name character varying)
;

INSERT INTO tableXX
    (file_name)
VALUES
    ('my_String1_20220103_144415.csv'),
    ('my_String2_20220106_155730.csv'),
    ('my_String3_20220108_153930.csv'),
    ('my_String4_20220103_144470.csv'),
    ('my_String5_20220103_144415.csv')
;

select REGEXP_REPLACE(file_name, '^([^_]*_[^_]*).*(\.[^.]*)$', '\1\2') as file_name  from tableXX

输出:

【讨论】:

    【解决方案2】:

    您要替换的字符串部分显然是日期时间。您不需要可能很慢的正则表达式。

    使用基本字符串函数(2个解决方案):

    SELECT
        OVERLAY(file_name placing '' from (LENGTH(file_name) - 19) for 17)
        , REVERSE(OVERLAY(REVERSE(file_name) PLACING '' FROM 4 FOR 16))
    FROM tableXX;
    

    OVERLAY 不接受负整数,这也是我使用LENGTH 的原因。

    但鉴于您想用它的特定格式替换这个日期时间值,如果您仍然想使用 RegEx 我建议这样做:

    SELECT REGEXP_REPLACE(file_name, '_[\d_]+.', '.')
    FROM tableXX;
    

    将以下划线开头、后跟整数或下划线并以点结尾的部分替换为单个点。

    【讨论】:

      【解决方案3】:

      还有一个不带正则表达式的选项:

      select concat(split_part(file_name, '_', 1), 
                    '_', 
                    split_part(file_name, '_', 2), 
                    '.', 
                    split_part(file_name, '.', 2))
      from the_table
      

      不确定哪一个会更快。正则表达式通常很慢,但使用split_part() 重复调用也可能不会很快。

      【讨论】:

        猜你喜欢
        • 2011-04-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-12-23
        • 2011-06-06
        • 1970-01-01
        • 2017-04-09
        • 2019-05-11
        相关资源
        最近更新 更多