如何在postgres查询中使用正则表达式来查找匹配后的所有文本

时间:2016-04-15 23:36:00

标签: sql regex postgresql pattern-matching

id | url
---------
1  | "facebook.com/user?query=hello"
2  | "stackoverflow.com/question/?query=postgres"
3  | "facebook.com/videos?"
4  | "facebook.com/user?query="

所以,这不是最好的例子,但基本上表中有一个字段,我查询的是一个URL并包含查询输入,我想只选择在{{{{{{{ 1}}

所以我想要获得第1行和第2行。

如果我能捕捉到之后会发生的事情,那会更酷吗? (query=hello

感谢您提供任何见解或帮助

3 个答案:

答案 0 :(得分:0)

您可以使用以下方式轻松选择行:

where url like '%query=_%'

您可以通过多种方式获得所需内容。这是一个简单的方法:

select (case when url like '%query=_%'
             then substr(url, position('query=' in url) + 6)
        end) as querystring
from pageviews;

答案 1 :(得分:0)

这是更友好的索引解决方案:

drop table if exists foo.t;
create table foo.t (x bigserial, url varchar);
insert into foo.t(url) values
  ('facebook.com/user?query=hello'),
  ('stackoverflow.com/question/?query1=postgres'),
  ('facebook.com/videos?'),
  ('facebook.com/user?query=');
insert into foo.t(url) select url from foo.t, generate_series(1,100000);
create index iturl on foo.t(position('?query=' in url), length(url));
explain analyze select * from foo.t where position('?query=' in url) > 0 and length(url) > position('?query=' in url) + 7;

结果是:

                                                         QUERY PLAN                                                          
-----------------------------------------------------------------------------------------------------------------------------
 Bitmap Heap Scan on t  (cost=3736.79..12211.16 rows=67005 width=37) (actual time=62.072..407.323 rows=100001 loops=1)
   Recheck Cond: ("position"((url)::text, '?query='::text) > 0)
   Filter: (length((url)::text) > ("position"((url)::text, '?query='::text) + 7))
   Rows Removed by Filter: 100001
   Heap Blocks: exact=3449
   ->  Bitmap Index Scan on iturl  (cost=0.00..3720.04 rows=201015 width=0) (actual time=60.473..60.473 rows=200002 loops=1)
         Index Cond: ("position"((url)::text, '?query='::text) > 0)
 Planning time: 0.512 ms
 Execution time: 423.587 ms
(9 rows)

请注意,我更改了您的初始数据以使索引可选(1/4点击)。

答案 2 :(得分:0)

您可以将通配符%like子句一起使用。

SELECT * FROM person WHERE email like '%gmail.com%';

这将从gmail.com表的email列中获取所有带有person的电子邮件。

以下部分可能与该问题无关,但如果有人想使用正则表达式

~字符可用于匹配正则表达式,例如

SELECT * FROM person WHERE email ~ '[A-Z]';

这将列出email列包含大写字母的所有行