如何从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
功能,可以删除尾随的|
字符。现在这个功能非常有效。