diff -r 30c0963a57d4 django/db/backends/mysql/base.py
--- a/django/db/backends/mysql/base.py	Sun Jun 17 05:00:15 2007 -0500
+++ b/django/db/backends/mysql/base.py	Sun Jun 17 19:42:00 2007 -0500
@@ -228,6 +228,8 @@ OPERATOR_MAPPING = {
     'iexact': 'LIKE %s',
     'contains': 'LIKE BINARY %s',
     'icontains': 'LIKE %s',
+    'regex': 'REGEXP BINARY %s',
+    'iregex': 'REGEXP %s',
     'gt': '> %s',
     'gte': '>= %s',
     'lt': '< %s',
diff -r 30c0963a57d4 django/db/backends/mysql_old/base.py
--- a/django/db/backends/mysql_old/base.py	Sun Jun 17 05:00:15 2007 -0500
+++ b/django/db/backends/mysql_old/base.py	Sun Jun 17 19:42:00 2007 -0500
@@ -229,6 +229,8 @@ OPERATOR_MAPPING = {
     'iexact': 'LIKE %s',
     'contains': 'LIKE BINARY %s',
     'icontains': 'LIKE %s',
+    'regex': 'REGEXP BINARY %s',
+    'iregex': 'REGEXP %s',
     'gt': '> %s',
     'gte': '>= %s',
     'lt': '< %s',
diff -r 30c0963a57d4 django/db/backends/postgresql/base.py
--- a/django/db/backends/postgresql/base.py	Sun Jun 17 05:00:15 2007 -0500
+++ b/django/db/backends/postgresql/base.py	Sun Jun 17 19:42:00 2007 -0500
@@ -261,6 +261,8 @@ OPERATOR_MAPPING = {
     'iexact': 'ILIKE %s',
     'contains': 'LIKE %s',
     'icontains': 'ILIKE %s',
+    'regex': '~ %s',
+    'iregex': '~* %s',
     'gt': '> %s',
     'gte': '>= %s',
     'lt': '< %s',
diff -r 30c0963a57d4 django/db/backends/postgresql_psycopg2/base.py
--- a/django/db/backends/postgresql_psycopg2/base.py	Sun Jun 17 05:00:15 2007 -0500
+++ b/django/db/backends/postgresql_psycopg2/base.py	Sun Jun 17 19:42:00 2007 -0500
@@ -206,6 +206,8 @@ OPERATOR_MAPPING = {
     'iexact': 'ILIKE %s',
     'contains': 'LIKE %s',
     'icontains': 'ILIKE %s',
+    'regex': '~ %s',
+    'iregex': '~* %s',
     'gt': '> %s',
     'gte': '>= %s',
     'lt': '< %s',
diff -r 30c0963a57d4 django/db/backends/sqlite3/base.py
--- a/django/db/backends/sqlite3/base.py	Sun Jun 17 05:00:15 2007 -0500
+++ b/django/db/backends/sqlite3/base.py	Sun Jun 17 19:42:00 2007 -0500
@@ -64,9 +64,10 @@ class DatabaseWrapper(local):
             }
             kwargs.update(self.options)
             self.connection = Database.connect(**kwargs)
-            # Register extract and date_trunc functions.
+            # Register extract, date_trunc, and regexp functions.
             self.connection.create_function("django_extract", 2, _sqlite_extract)
             self.connection.create_function("django_date_trunc", 2, _sqlite_date_trunc)
+            self.connection.create_function("regexp", 2, _sqlite_regexp)
         cursor = self.connection.cursor(factory=SQLiteCursorWrapper)
         cursor.row_factory = utf8rowFactory
         if settings.DEBUG:
@@ -164,7 +165,7 @@ def get_sql_flush(style, tables, sequenc
     """Return a list of SQL statements required to remove all data from
     all tables in the database (without actually removing the tables
     themselves) and put the database in an empty 'initial' state
-    
+
     """
     # NB: The generated SQL below is specific to SQLite
     # Note: The DELETE FROM... SQL generated below works for SQLite databases
@@ -182,7 +183,7 @@ def get_sql_sequence_reset(style, model_
     "Returns a list of the SQL statements to reset sequences for the given models."
     # No sequence reset required
     return []
-    
+
 def _sqlite_date_trunc(lookup_type, dt):
     try:
         dt = util.typecast_timestamp(dt)
@@ -195,6 +196,13 @@ def _sqlite_date_trunc(lookup_type, dt):
     elif lookup_type == 'day':
         return "%i-%02i-%02i 00:00:00" % (dt.year, dt.month, dt.day)
 
+def _sqlite_regexp(re_pattern, re_string):
+    import re
+    try:
+        return bool(re.search(re_pattern, re_string))
+    except:
+        return False
+
 # SQLite requires LIKE statements to include an ESCAPE clause if the value
 # being escaped has a percent or underscore in it.
 # See http://www.sqlite.org/lang_expr.html for an explanation.
@@ -203,6 +211,8 @@ OPERATOR_MAPPING = {
     'iexact': "LIKE %s ESCAPE '\\'",
     'contains': "LIKE %s ESCAPE '\\'",
     'icontains': "LIKE %s ESCAPE '\\'",
+    'regex': 'REGEXP %s',
+    'iregex': "REGEXP '(?i)' || %s",
     'gt': '> %s',
     'gte': '>= %s',
     'lt': '< %s',
diff -r 30c0963a57d4 django/db/models/fields/__init__.py
--- a/django/db/models/fields/__init__.py	Sun Jun 17 05:00:15 2007 -0500
+++ b/django/db/models/fields/__init__.py	Sun Jun 17 19:42:00 2007 -0500
@@ -169,7 +169,7 @@ class Field(object):
 
     def get_db_prep_lookup(self, lookup_type, value):
         "Returns field's value prepared for database lookup."
-        if lookup_type in ('exact', 'gt', 'gte', 'lt', 'lte', 'month', 'day', 'search'):
+        if lookup_type in ('exact', 'regex', 'iregex', 'gt', 'gte', 'lt', 'lte', 'month', 'day', 'search'):
             return [value]
         elif lookup_type in ('range', 'in'):
             return value
diff -r 30c0963a57d4 django/db/models/query.py
--- a/django/db/models/query.py	Sun Jun 17 05:00:15 2007 -0500
+++ b/django/db/models/query.py	Sun Jun 17 20:18:28 2007 -0500
@@ -20,6 +20,7 @@ QUERY_TERMS = (
     'gt', 'gte', 'lt', 'lte', 'in',
     'startswith', 'istartswith', 'endswith', 'iendswith',
     'range', 'year', 'month', 'day', 'isnull', 'search',
+    'regex', 'iregex',
 )
 
 # Size of each "chunk" for get_iterator calls.
@@ -748,6 +749,8 @@ def get_where_clause(lookup_type, table_
         return "%s%s IS %sNULL" % (table_prefix, field_name, (not value and 'NOT ' or ''))
     elif lookup_type == 'search':
         return backend.get_fulltext_search_sql(table_prefix + field_name)
+    elif lookup_type in ('regex', 'iregex'):
+        raise NotImplementedError
     raise TypeError, "Got invalid lookup_type: %s" % repr(lookup_type)
 
 def get_cached_row(klass, row, index_start, max_depth=0, cur_depth=0):
diff -r 30c0963a57d4 docs/db-api.txt
--- a/docs/db-api.txt	Sun Jun 17 05:00:15 2007 -0500
+++ b/docs/db-api.txt	Sun Jun 17 19:42:00 2007 -0500
@@ -1173,6 +1173,48 @@ Note this is only available in MySQL and
 Note this is only available in MySQL and requires direct manipulation of the
 database to add the full-text index.
 
+regex
+~~~~~
+
+Case-sensitive regular expression match.
+
+The regular expression syntax is that of the database backend in use; for the
+``sqlite`` backend, the syntax is that of Python's ``re`` module.
+
+Example::
+
+    Entry.objects.get(title__regex=r'^(An?|The) +')
+
+SQL equivalents::
+
+    SELECT ... WHERE title REGEXP BINARY '^(An?|The) +'; -- MySQL
+
+    SELECT ... WHERE title ~ '^(An?|The) +'; -- PostgreSQL
+
+    SELECT ... WHERE title REGEXP '^(An?|The) +'; -- sqlite
+
+Using raw strings for passing in the regular expression syntax is recommended.
+
+Regular expression matching is not supported on the ``ado_mssql`` and
+``oracle`` backends; these will raise a ``NotImplementedError``.
+
+iregex
+~~~~~~
+
+Case-insensitive regular expression match.
+
+Example::
+
+    Entry.objects.get(title__iregex=r'^(an?|the) +')
+
+SQL equivalents::
+
+    SELECT ... WHERE title REGEXP '^(an?|the) +'; -- MySQL
+
+    SELECT ... WHERE title ~* '^(an?|the) +'; -- PostgreSQL
+
+    SELECT ... WHERE title REGEXP '(?i)^(an?|the) +'; -- sqlite
+
 Default lookups are exact
 -------------------------
 
