Postgresql子字符串在尖括号和引号之间提取

时间:2015-01-22 17:02:27

标签: sql postgresql pattern-matching substring

我有一个包含xml的字段。我正在尝试从属性中提取数据,该属性后面跟着位于元素开始标记末尾的>

E.g。

我需要scale属性中的250。

<Request id=""1111"" order=""123456"" scale=""250""><Project file=""test.txt""/></Request>

我希望使用substring来提取它。所以我做了:

select substring(myxml from '%scale="#"%#""><Pro%' for '#') from mytable

这会返回250,这就是我想要的。

但问题是,其他记录的下一个元素并不总是以<Pro

开头

所以我试过这个

select substring(myxml from '%scale="#"%#""><%' for '#') from mytable

它返回:

250"><Project file="test.txt"/></Request>

我哪里错了?有没有更好的办法? 非常感谢。

1 个答案:

答案 0 :(得分:0)

如果您始终确定自己位于scale元素中的Request属性之后,那么这可能对您有用(我只在PG 9.3.5上尝试过这个):

SELECT (regexp_matches(myxml, '<Request[^>]*?\s+scale=""(\d+)""'))[1] AS scale FROM mytable;

一些人为的模拟数据(我改变了scale值和内部元素名称)作为演示:

postgres=# SELECT * FROM mytable;
                                             myxml                                         
-----------------------------------------------------------------------------------------------
 <Request id=""1111"" order=""123456"" scale=""250""><Project file=""test.txt""/></Request>
 <Request id=""1111"" order=""123456"" scale=""250""><Notproject file=""test.txt""/></Request>
 <Request id=""1111"" order=""123456"" scale=""253""><Notproject file=""test.txt""/></Request>
(3 rows)

postgres=# SELECT (regexp_matches(myxml, '<Request[^>]*?\s+scale=""(\d+)""'))[1] AS scale FROM mytable;
 scale
-------
 250
 250
 253
(3 rows)

我上面使用的正则表达式要求scale的值只包含数字。如果您的数据可能更加多样化,则捕获部分可能需要([^"]+)而不是(\d+)