我想获取用户输入(表示为
$dangerous_string
),并将其用作 MySQL 查询中正则表达式的一部分。
执行此操作的最佳方法是什么?我想使用用户的字符串作为文字 - 如果它包含任何在 MySQL RegEx 中有意义的字符,这些字符实际上不应该影响我的正则表达式。
$dangerous_string = $_GET["string"];
//do something here
$dangerous_string = what_goes_here($dangerous_string);
$sql = "SELECT * FROM table WHERE search_column REGEX '" . $mysqli->real_escape_string("[[:<:]]$dangerous_string") . "'";
//etc....
preg_quote
并手动替换 &
preg_quote
接受一个字符串并使用反斜杠转义特殊字符。它适用于 PHP 正则表达式,而不是 MySQL 正则表达式,并且它不会转义 &
,这是 MySQL 所需要的。所以我们只需要像这样修改即可:
function escape_regex_for_mysql($dangerous_string) {
return preg_replace('/&/', '\\&', preg_quote($dangerous_string));
}
请注意,您仍然应该在顶部使用准备好的语句(或
$mysqli->real_escape_string
),如下所示:
$query = $wpdb->prepare(
'SELECT * FROM table WHERE search_column REGEXP %s',
'[[:<:]]' . escape_regex_for_mysql($dangerous_string)
);
让我们看一下 MySQL 的文档,看看哪些字符需要转义。 文档说:
MySQL >= 8.0.4 使用 International Components for Unicode (ICU) 实现正则表达式支持,它提供完整的 Unicode 支持并且是多字节安全的。
那么让我们看一下ICU项目的文档:
\(集合之外)引用以下字符。必须加引号才能被视为文字的字符是 * ? + [ ( ) { } ^ $ | \ .
\(集合内)引用以下字符。必须加引号才能被视为文字的字符是 [ ] \ 根据上下文,可能需要加引号的字符是 - &
因此需要转义的特殊字符列表是
* ? + [ ] ( ) { } ^ $ \ . - &
。 preg_quote
转义除 &
之外的所有这些。它还会不必要地转义一些字符,但 MySQL 会按预期处理。
或者,您可以将
&
作为第二个参数添加到 preg_quote
以便对其进行转义,例如preg_quote('AT&T', '&')
AFAIK,MySQL 正则表达式没有转义的本机方法。您可以在 PHP 中使用 preg_quote (http://www.php.net/manual/en/function.preg-quote.php) 来完成此操作,这可能会为您完成这项工作,但显然不是为此目的而设计的。
如果我处于您的情况,我的首选方法是在 PHP 中构建正则表达式白名单,然后您可以将其应用于危险字符串:
$safeString = preg_replace('/[^\w]/','',$dangerousString);
这将从字符串中删除所有非单词字符(即除 A-Za-z0-9_ 之外的任何字符)。
注意,我相信给出的其他答案不会删除/转义正则表达式特殊字符,我相信这是您的要求。
您需要确保正确处理报价和报价 在传递到数据库之前。最好的方法是:
mysql_real_escape_string ([php doc][1])
此方法在 PHP 和 C++ mysql 客户端库中都可用。
这应该确保任何“dangerous_string”不再危险 并且可以在 RegEx 使用的带引号的字符串中使用。