如何使用ANY数组运算符的正则表达式

问题描述 投票:9回答:5

我有一个包含作者数组的列。如何使用~*运算符检查其值是否与给定的正则表达式匹配?

~*运算符在左侧检查字符串,在右侧使用正则表达式进行匹配。文档说明,ANY操作员必须在右侧

SELECT '^p' ~* ANY(authors) FROM book;

不起作用,因为PostgreSQL尝试将字符串^p与数组中包含的表达式进行匹配。

任何的想法?

regex arrays postgresql
5个回答
8
投票

第一个明显的想法是使用自己的regexp匹配运算符和commuted参数:

create function commuted_regexp_match(text,text) returns bool as
'select $2 ~* $1;'
language sql;

create operator ~!@# (
 procedure=commuted_regexp_match(text,text),
 leftarg=text, rightarg=text
);

然后你可以像这样使用它:

SELECT '^p' ~!@# ANY(authors) FROM book;

另一种不同的方式来查看它以取消数组并在SQL中表达ANY结构的等价物:

select bool_or(r) from 
  (select author ~* '^j' as r
    from (select unnest(authors) as author from book) s1 
  ) s2;

1
投票

您可以定义自己的运算符来执行您想要的操作。

颠倒参数的顺序并调用适当的函数:

create function revreg (text, text) returns boolean 
language sql immutable 
as $$ select texticregexeq($2,$1); $$;

(revreg ...请选择你喜欢的名字)。

使用我们的revreg()函数添加一个新运算符:

CREATE OPERATOR ### (
    PROCEDURE = revreg,
    LEFTARG = text,
    RIGHTARG = text
 );

测试:

 test=# SELECT '^p' ### ANY(ARRAY['ika', 'pchu']);
  t
 test=# SELECT '^p' ### ANY(ARRAY['ika', 'chu']);
  f
 test=# SELECT '^p' ### ANY(ARRAY['pika', 'pchu']);
  t
 test=# SELECT '^p' ### ANY(ARRAY['pika', 'chu']);
  t

请注意,您可能希望将JOIN和RESTICT子句设置为new运算符以帮助计划程序。


1
投票

我用这个:

create or replace function regexp_match_array(a text[], regexp text)
returns boolean
strict immutable
language sql as $_$
select exists (select * from unnest(a) as x where x ~ regexp);
$_$;

comment on function regexp_match_array(text[], text) is
  'returns TRUE if any element of a matches regexp';

create operator ~ (
 procedure=regexp_match_array,
 leftarg=text[], rightarg=text
);

comment on operator ~(text[], text) is
  'returns TRUE if any element of ARRAY (left) matches REGEXP (right); think ANY(ARRAY) ~ REGEXP';

然后使用它就像你使用〜文本标量一样:

=> select distinct gl from x where gl ~ 'SH' and array_length(gl,1) < 7;
┌──────────────────────────────────────┐
│                  gl                  │
├──────────────────────────────────────┤
│ {MSH6}                               │
│ {EPCAM,MLH1,MSH2,MSH6,PMS2}          │
│ {SH3TC2}                             │
│ {SHOC2}                              │
│ {BRAF,KRAS,MAP2K1,MAP2K2,SHOC2,SOS1} │
│ {MSH2}                               │
└──────────────────────────────────────┘
(6 rows)

1
投票

我的解决方案

SELECT a.* FROM books a
CROSS JOIN LATERAL (
   SELECT author
   FROM unnest(authors) author
   WHERE author ~ E'p$'
   LIMIT 1
)b;

使用交叉横向连接,对表“books”的每一行计算子查询,如果由unexst返回的行之一满足条件,则子查询返回一行(因为限制)。


1
投票
SELECT * FROM book where   EXISTS ( SELECT * from unnest(author) as X where x ~* '^p' )  
© www.soinside.com 2019 - 2024. All rights reserved.