Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/powerbi/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何从PostgreSQL中的文本中删除带分隔符的部分?_Sql_Regex_Postgresql_Replace_String Function - Fatal编程技术网

如何从PostgreSQL中的文本中删除带分隔符的部分?

如何从PostgreSQL中的文本中删除带分隔符的部分?,sql,regex,postgresql,replace,string-function,Sql,Regex,Postgresql,Replace,String Function,我想从字符串中删除一些文本模式,我的字符串有一个管道分隔符,并且参数并不总是相互跟随 这是我的绳子 TType=SEND|Status=OK|URL=min://j?_a=3&ver=1.1|day=3 我想消除TType=SEND和URL=min://j?\u a=3&ver=1.1 因此,我的最终结果应该是 Status=OK|day=3 我已经试过了。在postgresql中不工作 select REGEXP_REPLACE('TType=SEND|Status=OK|URL=

我想从字符串中删除一些文本模式,我的字符串有一个管道分隔符,并且参数并不总是相互跟随

这是我的绳子

TType=SEND|Status=OK|URL=min://j?_a=3&ver=1.1|day=3
我想消除
TType=SEND
URL=min://j?\u a=3&ver=1.1

因此,我的最终结果应该是

Status=OK|day=3
我已经试过了。在postgresql中不工作

select REGEXP_REPLACE('TType=SEND|Status=OK|URL=min://j?_a=3&ver=1.1|day=3', 
'(TType=.*?(\||$))|(URL=.*?(\||$))', '')

  • 将字符串拆分为参数,如
    A=B
    。将每个记录移动到单独的记录中
  • =
    字符处拆分这些元素,并筛选不带键的元素=
    TType
    URL
  • 最后,将所有这些第一次拆分聚合为一个字符串列表

  • 是有效的以下基于正则表达式的解决方案应该可以做到这一点:

    SELECT TRIM(REGEXP_REPLACE(
             'TType=SEND|Status=OK|URL=min://j?_a=3&ver=1.1|day=3', 
             '(TType|URL)=[^|]*(\||$)', '', 'g'), '|')
    -- outputs:
    -- Status=OK|day=3
    
    模式的工作原理:

    (TType|URL)=[^|]*(\||$)
    |-----------|----|-----
    1           2    3
    
  • 如果任何子字符串以
    TType
    URL
    开头,后跟
    =
  • 模式使用的字符不是
    |
  • 模式使用字符串的|或结尾
  • g
    标志在as中描述

    标志g指定替换每个匹配的子字符串,而不是仅替换第一个子字符串

    这在这里是必要的,因为我们想要替换所有与模式匹配的子字符串


    最后,有时一个
    |
    字符可能会保留在字符串的末尾。任何尾随的
    |
    字符都将使用
    TRIM

    从结果中修剪
    尝试的正则表达式存在一些问题:

  • 即使使用了非贪婪的
    *?
    匹配,也可能包括管道符号。这可以通过使用匹配器来纠正,该匹配器允许除管道符号以外的任何东西(这可能是贪婪的):
    [^ |]*
  • 它应该使用
    'g'
    标志来替换所有出现的事件,而不仅仅是第一个
  • 它只在末端查找管道,而不是在开始处。这意味着,如果最后一个管道与最后一个管道后的字符串相匹配(例如,在您的示例中,
    URL=…
    ),则它将在最后一个管道完好无损
  • 根据上述要点,以下是一个工作版本:

    选择REGEXP|u REPLACE('TType=SEND | Status=OK | URL=min://j?| u a=3&ver=1.1 | day=3','((Status | TType)=[^ |]*[|][|][|](Status | TType)=[^ |]*),'g')

    Rextester演示:

    回答:

    SELECT 
    REGEXP_REPLACE(
     REGEXP_REPLACE('TType=SEND|Status=OK|URL=min://j?_a=3&ver=1.1|day=3',
      '(TType|URL)=[^|]*\|?', '','g'),
    '\|$', '');
    
    说明:

  • 模式中的
    *?
    部分虽然不贪婪,但也会消耗冒号,因此不会按预期的方式运行。这是由使用任何非冒号字符的
    [^ |]*
    修复的,零次或多次

  • 然后您还需要添加全局标志“g”,以替换模式的所有出现,如中所述

  • 最后,如果需要消除的参数最后出现(因为参数可以以任何顺序出现),则需要添加额外的替换步骤以消除字符串末尾的剩余冒号

  • 例如,在没有额外步骤的情况下

    SELECT
    REGEXP_REPLACE('Status=OK|URL=min://j?_a=3&ver=1.1|day=3|TType=SEND',
      '(TType|URL)=[^|]*\|?', '','g');
    
    SELECT 
    REGEXP_REPLACE(
     REGEXP_REPLACE('Status=OK|URL=min://j?_a=3&ver=1.1|day=3|TType=SEND',
      '(TType|URL)=[^|]*\|?', '','g'),
    '\|$', '');
    
    产生

    Status=OK|day=3|
    
    同时,添加额外的步骤,如下所示

    SELECT
    REGEXP_REPLACE('Status=OK|URL=min://j?_a=3&ver=1.1|day=3|TType=SEND',
      '(TType|URL)=[^|]*\|?', '','g');
    
    SELECT 
    REGEXP_REPLACE(
     REGEXP_REPLACE('Status=OK|URL=min://j?_a=3&ver=1.1|day=3|TType=SEND',
      '(TType|URL)=[^|]*\|?', '','g'),
    '\|$', '');
    
    产生所需的结果

    Status=OK|day=3
    

    @WiktorStribiżew无法删除其分隔符中的URL参数。字符串不总是动态的,内容不总是相同的,因此TType不总是出现在起始位置,好的,我明白了,这些参数是连续的。@WiktorStribiżew运气好吗?如果我可以在select语句中
    之前使用它。从
    哪一部分?WHERE或regexp_split_to_表?与子查询一起使用:在那里,您可以使用一个FILTER子句,而不是WHERE子句:解决方案没有问题,但是我希望解决方案介于
    select
    from
    之间。i、 e.
    从表中选择(此处的解决方案)
    great soln
    (Status | TType | day)=[^ |]*([|]|$)
    为什么这样会在结果的末尾留下一个管道。这是因为正则表达式只在每个匹配的末尾而不是开始寻找管道符号(或者文本的结尾)。如果您需要处理这个问题,那么不幸的是,您将需要一些重复,因为您需要在开始或结束时查找管道,而不是在两者之间:
    ((Status | TType | day)=[^ |]*[|][|](Status | TType | day)=[^ |]*
    。(现在已相应地编辑了我的答案)。谢谢,
    (状态| TType | day)=[^ |]*(\\| |$)
    我已经尝试过了,一切正常。是否可以从上面的正则表达式中移除末端的管道。这是结果
    URL=min://j?\u a=3&ver=1.1
    @omarivectoromosa,请参阅更新的答案。使用
    TRIM
    功能,可以删除尾随的
    |
    字符。现在这个功能非常有效。