我的表格中的条目类似于“XXX010101 somethingelse XXX010102”。
我想从中提取XXX01 ...部分 - 如果需要可能会使用一些分隔符 - 现在我可以轻松地使用以下内容取出第一个:
select distinct substring(content from 'XXX[0-9]+'), content from data where content ~ 'XXX[0-9]+'
我的一个想法就是创建一些怪物正则表达式来替换不是XXX子串的所有内容......但是为了更简单的解决方案(如ag标记到子串),我希望(并且找不到)。 / p>
环顾四周时,我发现8.3引入了一个regex_matches函数,这似乎是我需要的东西 - 8.2中有什么替代品吗?或者在8.2中轻松获得它?
你会如何解决这个问题?或者升级是我最好的选择? ;)(这是一个生产系统,因此停机后的停机时间和一些问题的风险是犹豫的来源)。
提前致谢。
- 预期产量增加 -
代表
"something XXX010101 something else XXX010102"
我想得到:
XXX010101
XXX010102
OR(不太可取)
XXX010101,XXX010102
答案 0 :(得分:2)
我甚至对发布我的答案犹豫不决。你真的必须升级。版本8.2现在即将结束。点击链接@a_horse_with_no_name发布。
然而,问题引起了我的注意。以下演示适用于 PostgreSQL 8.2 :
SELECT -- content,
rtrim(
regexp_replace(
regexp_replace(
replace(
substring(content
,E'(XXX\\d+|XXX\\d+.*XXX\\d+)') -- kill leading / trailing noise
,',',' ') -- remove all ","
,E'(XXX\\d+)', E'\\1,', 'g') -- terminate X-strings with ","
-- now we can use non-greedy terminated with ","
,E'(XXX\\d+?,)*?.*?(XXX\\d+?,)', E'\\1\\2', 'g')
,',') AS result
FROM (VALUES
('no match')
,('XXX010101')
,('XXX010102 beginn')
,('end XXX010103')
,('middle XXX010104 match')
,('match middle XXX010105 and end XXX010106')
,('XXX010107, match beginn XXX010108 & middle')
,('XXX010109 begin and end XXX010110')
,('XXX01011 begin XXX010112 middle and end XXX010113')
,('XXX01014 begin XXX010115 close matches XX010113 XXXy010113 23624 ,XXX010116')
,('f XXX01017 B XXX010118 457XXX010119 XXXy XXX010120 overkill XXX010121end')
) data(content)
结果:
result
--------------------------------------------------
-- first line is NULL
XXX010101
XXX010102
XXX010103
XXX010104
XXX010105,XXX010106
XXX010107,XXX010108
XXX010109,XXX010110
XXX01011,XXX010112,XXX010113
XXX01014,XXX010115,XXX010116
XXX01017,XXX010118,XXX010119,XXX010120,XXX010121
regex_matches()
,如OP已经陈述的regexp_replace()
可以使用g
标记(以g
为标题),
的所有其他出现后,使用,
终止所需的字符串可能是任何不属于所需字符串的字符,但,
可以作为分隔符结果。(XXX\\d+?,)*?
来捕获任意数量的有用字符串。 final rtrim()
删除尾随,
在PsotgreSQL 8.3+中,您可以使用regexp_split_to_table()
将所需的字符串拆分为单行。在8.2你必须提出自己的东西。我会写一个plgpsql函数......
这大量使用了PostgreSQL POSIX Regular Expressions的功能(链接到8.2版本)。
答案 1 :(得分:1)
这样的事情怎么样(假设你要找的值都包含在一个单独的表格中)......虽然我不会声称表现良好......
Select A.text, B.Text2, B.Val
FROM A
INNER JOIN B ON B.Text2 LIKE ('%' || A.Text || '%')
让表格A包含您正在寻找的所有可能的XXX010101组合
text
XXX010101
XXX010102
XXX010103
让表B包含您想要的所有搜索文本
text 2 val
something XXX010101 something else XXX010102 1
yet another XXX010102 and this XXX010103 2
XXX010105 3
XXX010103 4
结果:
text text2 VAL
XXX010101 something XXX010101 something else XXX010102 1
XXX010102 something XXX010101 something else XXX010102 1
XXX010102 yet another XXX010102 and this XXX010103 2
XXX010103 yet another XXX010102 and this XXX010103 2
XXX010103 XXX010103 4
--------错误但误解了这个问题......
更换功能有什么问题? http://www.postgresql.org/docs/8.2/interactive/functions-string.html
replace( 'abcdefabcdef', 'cd', '')
所以字符设置为空字符串。
答案 2 :(得分:0)
最快的方法是使用plperlu which works with 8.2.
CREATE LANGUAGE plperl
CREATE FUNCTION get_things(inputStr text)
RETURNS SETOF text
AS $BODY$
return \@{[ $_[0] =~ m/(XXX\d{6})/g ]}
$BODY$
LANGUAGE plperl
IMMUTABLE;
SELECT get_things(x)
FROM ( VALUES
('XXX010101 somethingelse XXX010102')
) AS t(x);
get_things
------------
XXX010101
XXX010102
(2 rows)
它也适用于PostgreSQL的新版本。