在 MySQL 中转义用户输入正则表达式的最佳方法是啥?
Posted
技术标签:
【中文标题】在 MySQL 中转义用户输入正则表达式的最佳方法是啥?【英文标题】:What's the best way to escape user input for Regular Expressions in MySQL?在 MySQL 中转义用户输入正则表达式的最佳方法是什么? 【发布时间】:2011-04-16 11:49:01 【问题描述】:我想获取用户输入,表示为 $dangerous_string,并将其用作 mysql 查询中 RegEx 的一部分。
执行此操作的最佳方法是什么?我想将用户的字符串用作文字——如果它包含任何在 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....
【问题讨论】:
【参考方案1】:AFAIK,MySQL 正则表达式没有本地转义方式。您可以使用 preg_quote (http://www.php.net/manual/en/function.preg-quote.php) 在 PHP 中执行此操作,这可能会为您完成这项工作,但显然不是为此目的而设计的。
如果我遇到您的情况,我首选的方法是在 PHP 中构建一个正则表达式白名单,然后您可以将其应用于您的危险字符串:
$safeString = preg_replace('/[^\w]/','',$dangerousString);
这会从您的字符串中删除所有非单词字符(即除 A-Za-z0-9_ 之外的任何字符)。
注意,我相信给出的其他答案不会删除/转义正则表达式特殊字符,我相信这是您的要求。
【讨论】:
【参考方案2】:使用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 的文档,看看哪些字符需要转义。 The documentation 说:
MySQL >= 8.0.4 使用 Unicode 国际组件 (ICU) 实现正则表达式支持,它提供完整的 Unicode 支持并且是多字节安全的。
那么让我们看看the documentation for the ICU project:
\(在集合之外)引用以下字符。必须引用才能被视为文字的字符是 * ? + [ ( ) ^ $ | \ .
\(在集合内)引用以下字符。必须引用才能被视为文字的字符是 [ ] \ 根据上下文可能需要引用的字符是 - &
所以需要转义的特殊字符列表是* ? + [ ] ( ) ^ $ \ . - &
。 preg_quote
转义除&
之外的所有这些。它还不必要地转义了一些字符,但 MySQL 会按预期处理。
或者,您可以将&
作为第二个参数添加到preg_quote
以使其被转义,例如preg_quote('AT&T', '&')
【讨论】:
似乎 reg exps 必须使用双斜杠而不是单斜杠才能正常工作。 str_replace('\\', '\\\\', preg_replace('/&/', '\\&', preg_quote($dangerous_string))) @luky 您的示例中的双斜杠在那里,因为您使用的是字符串文字。如果您要运行echo '\`;
或echo '\\&'
,您只会看到一个反斜杠。该示例中的函数echo
仅接收一个反斜杠。使用字符串文字时需要正确转义,此外还需要使用 preg_quote
转义以用于此问题中的用途。
我没有使用任何文字,我使用的是函数 preg_quote 和变量,我相信 mysql 本身需要双斜杠。【参考方案3】:
您需要确保正确处理引号和刻度 在传递到数据库之前。最好的方法是:
mysql_real_escape_string ([php doc][1])
此方法在 PHP 和 C++ mysql 客户端库中都可用。
这应该确保任何 'dangerous_string' 不再危险 并且可以在 RegEx 使用的带引号的字符串中使用。
【讨论】:
对 REGEXP 解释没有任何作用,这就是问题所在。以上是关于在 MySQL 中转义用户输入正则表达式的最佳方法是啥?的主要内容,如果未能解决你的问题,请参考以下文章