dan*_*lin 3 postgresql view pattern-matching postgresql-9.0
我试图在 Postgres 9.0 的 PostGIS 中填充一个视图,在这个视图中我希望它包含一个基于 2 个字符串位置的子字符串。请参阅下面的我的代码。
CREATE OR REPLACE VIEW vw_actions AS
SELECT ls.f_table_schema, ls.f_table_name,
(SELECT substr(ls.attribute_actions_text,
strpos(ls.attribute_actions_text, 'name="')+6,
strpos(ls.attribute_actions_text, '"/>') -
strpos(ls.attribute_actions_text, 'name="'))) AS actions
FROM layer_styles ls;
Run Code Online (Sandbox Code Playgroud)
结果是它在使用 strpos 时不喜欢负数。我可以让它前进 6 个字符以从返回的子字符串中删除 'name="' 但不能删除 '"/>'。
它返回以下内容:
View SHED Database"/>
Run Code Online (Sandbox Code Playgroud)
我希望它返回的地方:
View SHED Database
Run Code Online (Sandbox Code Playgroud)
任何建议将不胜感激。
补充:我发现如果我使用 9.1,我可以使用 strposrev 并且我认为以下代码会起作用:
CREATE OR REPLACE VIEW vw_actions AS
SELECT ls.f_table_schema, ls.f_table_name,
(SELECT substr(ls.attribute_actions_text::text,
strpos(ls.attribute_actions_text::text, 'name="'::text)+6,
strposrev(ls.attribute_actions_text::text, '"/>'::text)+3 -
strpos(ls.attribute_actions_text::text, 'name="'::text))) AS actions
FROM layer_styles ls;
Run Code Online (Sandbox Code Playgroud)
使用带有正则表达式的substring()代替:
substring(ls.attribute_actions_text FROM 'name="(.*?)"/>')
Run Code Online (Sandbox Code Playgroud)
点 ( .) 匹配任何字符,*?是0 个或多个匹配序列的非贪婪量词,括号 ( ()) 标记要返回的子字符串。
与您的代码一样,这将选择与模式匹配的第一个字符串,并且不会进一步查找。
此外,您不需要将表达式设为子查询,这只会增加开销:
CREATE OR REPLACE VIEW vw_actions AS
SELECT ls.f_table_schema
, ls.f_table_name
, substring(ls.attribute_actions_text FROM 'name="(.*?)"/>') AS actions
FROM layer_styles ls;
Run Code Online (Sandbox Code Playgroud)
快速测试用例(您应该提供):
SELECT *, substring(ls.attribute_actions_text FROM 'name="(.*?)"/>')
FROM (
VALUES
('bar name="View SHED Database"/> foo')
, ('bar name="View SHED Database"/> fooname="View SHED Database"/>xx')
, ('name="buntch a bull"/> fooname="View SHED Database"/>xx')
, ('xxname="bla foo grr"/>')
, ('')
, (NULL)
) ls(attribute_actions_text)
Run Code Online (Sandbox Code Playgroud)