我想从字符串中删除一些文本模式,我的字符串有一个管道分隔符,并且参数并不总是相互跟随。
这是我的字符串
TType=SEND|Status=OK|URL=min://j?_a=3&ver=1.1|day=3
我想消除TType=SEND
和URL=min://j?_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=.*?(\||$))', '')
答案 0 :(得分:5)
答案:
SELECT
REGEXP_REPLACE(
REGEXP_REPLACE('TType=SEND|Status=OK|URL=min://j?_a=3&ver=1.1|day=3',
'(TType|URL)=[^|]*\|?', '','g'),
'\|$', '');
说明:
模式中的 .*?
部分虽然不是贪婪的,但也消耗了冒号,因此行为不符合预期。这是由 [^|]*
修复的,它消耗任何非冒号字符零次或多次。
然后您还需要添加全局标志“g”,以替换所有出现的模式,如 documentation 中所述。
最后,如果您需要消除的参数最后出现(因为参数可以按任意顺序出现),您需要添加额外的替换步骤以消除字符串末尾的残留冒号。< /p>
例如没有额外的步骤,如下
SELECT
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(
REGEXP_REPLACE('Status=OK|URL=min://j?_a=3&ver=1.1|day=3|TType=SEND',
'(TType|URL)=[^|]*\|?', '','g'),
'\|$', '');
产生想要的
Status=OK|day=3
答案 1 :(得分:3)
SELECT
string_agg(elements,'|') -- 3
FROM mytable,
regexp_split_to_table(mystring, '\|') as elements -- 1
WHERE split_part(elements, '=', 1) = ANY(ARRAY['TType', 'URL']) IS NOT TRUE -- 2
A=B
之类的参数。将每个移到单独的记录中=
字符处拆分这些元素并过滤没有键 = TType
或 URL
的元素答案 2 :(得分:2)
The S-Man's answer 是一个有效的 ?
<块引用>当然赞成,解决方案还可以,但它不能完全满足我的问题。因为我希望解决方案在 select 和 from 内
如果这是“强制性”要求,那么我会看到以下选项:
最终查询可能如下所示:
SELECT t.*, s.result
FROM t
LEFT JOIN LATERAL (
SELECT string_agg(elements,'|') AS result
FROM regexp_split_to_table(t.col, '\|') as elements
WHERE split_part(elements, '=', 1) = ANY(ARRAY['TType', 'URL']) IS NOT TRUE) s ON TRUE
或者在 SELECT 列表中使用子查询:
SELECT t.*,
(
SELECT string_agg(elements,'|') AS result
FROM regexp_split_to_table(t.col, '\|') as elements
WHERE split_part(elements, '=', 1) = ANY(ARRAY['TType', 'URL']) IS NOT TRUE
) AS result
FROM t
答案 3 :(得分:2)
以下基于正则表达式的解决方案应该可以解决问题:
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
标志在 documentation 中被描述为
标志 g 指定替换每个匹配的子字符串,而不仅仅是第一个。
这里是必要的,因为我们要替换与我们的模式匹配的所有子字符串。
最后,有时单个 |
字符可能会保留在字符串的末尾。使用 |
trimmed
字符都是 TRIM
答案 4 :(得分:2)
您尝试的正则表达式存在一些问题:
.*?
匹配,这仍可能包含管道符号。这可以通过使用允许除了管道符号之外的任何东西的匹配器来纠正(这可能是贪婪的):[^|]*
'g'
标志来替换所有的匹配项,而不仅仅是第一个。URL=...
在您的示例中)。根据以上几点,这是一个工作版本:
SELECT REGEXP_REPLACE('TType=SEND|Status=OK|URL=min://j?_a=3&ver=1.1|day=3', '((Status|TType)=[^|]*[|]|[|](Status|TType)=[^|]*)', '', 'g')
Rextester 演示: https://rextester.com/CYBP40923