Home > OS >  Postgresql regex match string with substring
Postgresql regex match string with substring

Time:10-30

I have a string foo,bar what i want to do is to form a query matching both of them (can have gap between them)

for example it should be matching against entries like

aaa,bbbb,foo,zzz,bar
bar,ccc,ddddd,foo,iiiii

but not

aaa,eeeee,foo,rrrrrr,hhhhhh
ooooo,ii,sssss,bar,xxxx

the column that i'm trying to matching against is of type text

i tried doing it like this

select * from string_entries where str similar to '%(?=.*foo)(?=.*bar)%';

but i'm getting this error

ERROR:  invalid regular expression: quantifier operand invalid
SQL state: 2201B

CodePudding user response:

Assuming these values must appear as full comma-separated entries, you can use

where str ~ '^(?=.*(?:,|^)foo(?:,|$))(?=.*(?:,|^)bar(?:,|$))'

Here, it will match strings that contain foo and bar in any order using the ~ (regex matching) operator. Details:

  • ^ - start of string
  • (?=.*(?:,|^)foo(?:,|$)) - immediately on the right, there should be any zero or more chars, as many as possible, and then a foo string (either at the start of string or right after a comma and followed with a comma or end of string position)
  • (?=.*(?:,|^)bar(?:,|$)) - immediately on the right, there should be any zero or more chars, as many as possible, and then a bar string (either at the start of string or right after a comma and followed with a comma or end of string position)

Assuming these values must appear as whole words you can replace the non-capturing groups with \y word boundaries and use

where str ~ '^(?=.*\yfoo\y)(?=.*\ybar\y)'

See the enter image description here

CodePudding user response:

I am inclined to not do this with a regex comparison, but convert the string into an array:

select *
from string_entries 
where string_to_array(str, ',') @> array['foo', 'bar']

This will only work if you need equality comparison. If you wanted to also match using e.g. foo% rather than foo then this would work.

  • Related