PHP函数用于转义MySQL正则表达式语法

15
我正在寻找类似于 preg_quote 的东西,但适用于 MySQL 正则表达式语法。
有任何想法吗?

5个回答

12

MySQL正则表达式使用的是“扩展”POSIX变体(ERE),在PHP中作为已弃用的ereg_函数提供。

不幸的是,在PHP中没有ereg_quote函数,但PCRE的特殊字符是ERE特殊字符的超集,并且对非特殊标点字符进行反斜杠转义不会损害它,因此您可以安全地使用preg_quote

(当然,在引用后,您需要使用参数化查询或mysql_real_escape_string来防止反斜杠被解释为MySQL的非ANSI标准字符串字面量转义字符。)


3
小小注意:空控制字符。preg_quote将其转义为\000,但MySQL无法识别这种格式。不过,MySQL的正则表达式引擎本来就无法处理空字符,它们会被视为终止符。 - bobince
2
我必须使用str_replace('?','\?',preg_quote()),因为preg_quote()在不知道特殊UTF8字符时会产生'?'。而且,在正则表达式中需要对'?'进行转义。 - JochenJung
一个问题!mysql_real_escape_string将转义反斜杠字符。这个特性会导致所有反斜杠再次被转义(如果您在引用后使用mysql_real_escape_string)! - Mir-Ismaili
@Mir-Ismaili 是的,如果您将正则表达式注入到 SQL 查询字符串文字中,则应仅使用 mysql_real_escape_string,在这种情况下,您确实需要额外的反斜杠。通常,最好使用参数化查询并避免需要额外转义。 - bobince
为了完整回答:要使用参数化的 REGEXP,您可以像这样使用 CONCATWHERE field REGEXP CONCAT('regexp part 1', ?, 'regexp part 2') 并将 preg_quote($field) 绑定到 ? 参数。 - Ruslan Stelmachenko

5

很遗憾,PHP的preg_quote()函数通过转义冒号符号(:)破坏了MySQL正则表达式,而MySQL的正则表达式无法理解这种转义符号。


1
那么,preg_quote 的最佳处理方法是将所有转义的冒号替换为未转义的冒号吗? - Nathan Stretch
我认为这个答案不正确。请尝试使用MySQL:$statement = $wpdb->prepare( "SELECT %s REGEXP %s", 'hello:you', 'hello\\:you' ) - Flimm

1
尝试这个:(PHP)
    $tags="test'*\\\r blue";
    $tags=mysql_real_escape_string($tags);
    $tags=preg_replace('/([.*?+\[\]{}^$|(\)])/','\\\\\1',$tags);
    $tags=preg_replace('/(\\\[.*?+\[\]{}^$|(\)\\\])/','\\\\\1',$tags);

1

这方面没有原生的MySQL函数。在将正则表达式传递给MySQL查询之前,您可能只需要使用preg_quote


preg_quote 不会转义 &,而 MySQL 需要它。 - Flimm

0

感谢@bobince的好答案。但是如果您需要在引用后使用mysql_real_escape_string,它会有一个问题,我在评论中提到了这一点。

实际上,preg_quotemysql_real_escape_string有重叠,这就造成了问题!mysql_real_escape_string在这种情况下不应该转义\。所以我建议:

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
}

(有关charlist请参见:http://php.net/manual/en/mysqli.real-escape-string.php

我知道这不是最理想的方法,但找不到更好的方法。


使用正则表达式转义和 mysql_real_escape_string 转义应该不会有问题。 - Flimm

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接