postgresql 子字符串和模式匹配从postgres中的字符串中提取数据

hc2pp10m  于 2023-03-29  发布在  PostgreSQL
关注(0)|答案(1)|浏览(134)

我和postgres 11一起工作。
我有文本,我想从这些文本中提取子字符串:
"|a john dumas .|d 1941|e united states|=^A22306"正确的输出应该是john大仲马.1941
"|a john dumas .|e united states|=^A22306"正确的输出应该是john大仲马.
"|a john dumas .|=^A22306 |e united states |d 1941 |f admin "正确的输出应该是john大仲马.1941
"|a john dumas .|f admin |d 1941 |=^A22306 |e united states"正确的输出应该是john大仲马.1941
"|a john dumas .|f admin |d 1941 "正确的输出应该是john大仲马.1941
"|a john dumas . "正确的输出应该是john大仲马.
"john dumas .|e united states |d 1941 "正确的输出应该是john大仲马.1941
"john dumas ."正确的输出应该是john大仲马.
如果文本包含|a,则从|a读取,直到找到第一个字符|,如果文本包含|d,则从|d读取,直到找到|d之后的第一个字符|,如示例1、3和4
如果文本包含|a,则从|a读取,直到找到第一个字符|,并且如果文本包含|d,并且在|d之后不包含任何字符|,则从|d读取,直到文本结束,如示例5
如果文本包含|a,并且如果文本在|a之后不包含任何字符|,则从|a读取,直到文本结束,如示例6
如果文本包含|a并且不包含任何字符|d,则从|a读取,直到找到|a之后的第一个字符|,如示例2
如果文本不包含|a,则从文本的开头读取,直到找到第一个字符|,并且如果文本包含|d并且不包含|d之后的任何字符|,则从|d读取,直到文本的结尾,如示例7
如果文本不包含|a并且不包含任何字符|,则像示例8一样从开始读取所有文本
所有示例的主要目标是从|a|d读取,如果文本不包含|a,则从文本的开头读取。

我想选择一个查询,它可以处理所有这些示例。

我尝试使用这段代码,但问题是这段代码只给予了第一个示例的正确输出

select  replace(substring('|a john dumas .|d 1941|e united states|=^A22306' from '\|a(.+)\|e'), '|d', '')

输出正确" john dumas . 1941"
有人能帮我解决这个问题吗

tv6aics1

tv6aics11#

您可以尝试以下查询

WITH data AS 
         (SELECT '|a john dumas .|d 1941|e united states|=^A22306' AS input
UNION ALL SELECT '|a john dumas .|e united states|=^A22306' AS input
UNION ALL SELECT '|a john dumas .|=^A22306 |e united states |d 1941 |f admin ' AS input
UNION ALL SELECT '|a john dumas .|f admin |d 1941  |=^A22306 |e united states' AS input
UNION ALL SELECT '|a john dumas .|f admin |d 1941 ' AS input
UNION ALL SELECT '|a john dumas . ' AS input
UNION ALL SELECT '|a john dumas .|d ت. 1941-|e محرر.|=^A22306' AS input
UNION ALL SELECT 'john dumas .|d 1941|e united states ' AS input  
UNION ALL SELECT 'john dumas .' AS input)

SELECT CONCAT(
       SUBSTRING(input, '^(?:\|a\s*)?([^|]+)'),
       SUBSTRING(input, '(?:\|d\s*)([^|]+)')) AS output
FROM data

参见here演示

相关问题