Out of the box, sqlite3 almost supports regular expressions, but not quite. It defines an REGEXP
keyword, but doesn’t provide an implementation.
It does, however, provide a very easy means through which to add your own implementation by offering the sqlite3_create_function_v2 function that you can call passing a function pointer.
For example, all you need to do to provide basic regular expression handling is to create a function that looks like:
static void my_sqlite_regexp(sqlite3_context *context, int argc, sqlite3_value **argv) { NSUInteger numberOfMatches = 0; if (argc == 2) { NSString *pattern = [NSString stringWithUTF8String:(const char *)sqlite3_value_text(argv[0])]; NSString *value = [NSString stringWithUTF8String:(const char *)sqlite3_value_text(argv[1])]; if (pattern != nil && value != nil) { NSError *error = nil; // assumes that it is case sensitive. If you need case insensitivity, then prefix your regex with (?i) NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:pattern options:kNilOptions error:&error]; if (regex != nil) numberOfMatches = [regex numberOfMatchesInString:value options:0 range:NSMakeRange(0, [value length])]; } } sqlite3_result_int(context, (int)numberOfMatches); }
And then register this function just after opening your database by calling:
sqlite3 *db; sqlite3_open("myfile.db", &db) sqlite3_create_function_v2(db, "REGEXP", 2, SQLITE_ANY, 0, my_sqlite_regexp, NULL, NULL, NULL);
From this point on, your function will be called if you use something like the following SQL (it looks for strings that start with Tiger
):
SELECT * FROM MY_TABLE WHERE MY_COL REGEXP '^Tiger.*'
A tutorial on regular expressions is beyond this post, but you can also provide any regex syntax that NSRegularExpresion
supports such as the case sensitivity markers. An example of searching for strings that match tiger
without caring about case might be:
SELECT * FROM MY_TABLE WHERE MY_COL REGEXP '(?i)^tiger.*'
Easy as pie.