web-dev-qa-db-ja.com

2つの文字列フラグメント間の部分文字列を検索する

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;

その結果、strposを使用する場合、マイナスの数値は好きではなくなります。返された部分文字列から 'name = "を削除するために6文字進むことができますが、'" /> 'は削除できません。

以下を返します。

View SHED Database"/> 

私がそれを返したいところ:

View SHED Database

任意の提案をいただければ幸いです。

[〜#〜] addition [〜#〜]: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;
3
daniel franklin

代わりに、正規表現で substring() を使用します。

substring(ls.attribute_actions_text FROM 'name="(.*?)"/>')

ドット(.)はany文字に一致し、*?は、貪欲でない 量指定子 であり、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;

クイックテストケース(提供されているはずです):

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)
5