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 afoo
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 abar
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)'
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.