~ / ~* / !~ / !~*
PG 7.4+→ booleanPOSIX regex match operators. ~ (case-sensitive match), ~* (case-insensitive), !~ (not match), !~* (not match, case-insensitive).
Signatures
string ~ pattern → booleanstring ~* pattern → booleanstring !~ pattern → booleanstring !~* pattern → booleanParameters
| Parameter | Type | Description |
|---|---|---|
| string | text | String to test |
| pattern | text | POSIX regular expression |
Examples
SELECT 'foobar' ~ 'foo';trueSELECT 'FooBar' ~* 'foo';true (case-insensitive)SELECT * FROM users WHERE email ~ '@gmail\.com
;Gmail usersSELECT * FROM logs WHERE message !~ 'DEBUG|INFO';Non-debug/info log linesA bare col ~ 'pattern' with no index causes a full sequential scan. For large tables with flexible pattern searches, a pg_trgm GIN index accelerates ~ queries by orders of magnitude. For structured full-text search, consider tsvector/tsquery instead.
✓ Instead: -- Sequential scan on large table (slow): SELECT * FROM articles WHERE body ~ 'postgres(ql)?'; -- Add trigram index first: CREATE INDEX ON articles USING GIN (body gin_trgm_ops); -- Now the same query uses the index.
Regex patterns without a leading literal prefix can't use a B-tree index. Create a GIN trigram index with `CREATE INDEX ON t USING GIN (col gin_trgm_ops)` to accelerate `col ~ pattern` queries.
CREATE INDEX ON products USING GIN (description gin_trgm_ops);
SELECT * FROM products WHERE description ~ 'wire(less)?';Fast regex search with trigram index