I'm looking for something similar to preg_quote, but for the MySQL regexp syntax.
Any ideas?
MySQL regexps are the ‘extended’ POSIX variant (ERE), available in PHP as the deprecated ereg_ functions.
Unfortunately there is no ereg_quote in PHP, however PCRE's special characters are a superset of ERE's special characters, and backslash-escaping a non-special punctuation character doesn't harm it, so you can get away with using preg_quote safely.
(Naturally you will need parameterised queries or mysql_real_escape_string after that quoting, to stop the backslashes being misinterpreted as MySQL's non-ANSI-standard string literal escapes.)
preg_quote escapes it to \000, which is a format MySQL doesn't recognise. But then MySQL's regex engine can't cope with null characters anyway, it takes them as terminators.mysql_real_escape_string will escape backslash characters. This feature causes all backslashes to be escaped again (if you use mysql_real_escape_string after quoting)!mysql_real_escape_string if you are injecting the regex into a SQL query string literal, in which case you do actually need the extra backslashes. Normally, it would be better to use parameterised queries and avoid the need for extra escaping.CONCAT like this: WHERE field REGEXP CONCAT('regexp part 1', ?, 'regexp part 2') and bind preg_quote($field) to ? parameter.Sadly, PHP's preg_quote() messes up MySQL REGEXP by escaping a colon sign (:) which MySQL's REGEXP does not understand
$statement = $wpdb->prepare( "SELECT %s REGEXP %s", 'hello:you', 'hello\\:you' )There's no native MySQL function for that. You might just need to use preg_quote before passing the regular expression to the MySQL query.
preg_quote does not escape & which is needed for MySQL.Thank @bobince's good answer. But it has a problem if you need to use mysql_real_escape_string after quoting, that I mentioned it in a comment.
Actually preg_quote and mysql_real_escape_string have overlap and it makes this problem! mysql_real_escape_string must not escape \ in this case. So I suggest:
function regexpEscape(/*string*/ $input) { // Uncomment `string` for PHP 7.0+
return addcslashes(preg_quote($input), "\0'\"\n\r\x1A"); // charlist = All characters that escape by real_escape_string except backslash
}
(For charlist see: http://php.net/manual/en/mysqli.real-escape-string.php)
I know this is not an ideal way, but couldn't find a better way.
mysql_real_escape_string