我试图从Perl程序中编写mysql中的正则表达式.我想要查询如下:
WHERE a.keywords REGEXP '[[:<:]]something[[:>:]]'
Run Code Online (Sandbox Code Playgroud)
但是,在Perl中,当我进行此查询时,我在连接时遇到错误:
for($i=0;$i<$count;$i++){
$where = $where . "'[[:<:]]$andkeywords[$i][[:>:]]' "; #errors
Run Code Online (Sandbox Code Playgroud)
这不会给我一个错误:
for($i=0;$i<$count;$i++){
$where = $where . "'[[:<:]] $andkeywords[$i] [[:>:]]' "; #no error
Run Code Online (Sandbox Code Playgroud)
在"无错误"代码中注意有额外的空格.但是如果我有额外的空间,那么我就不会得到我想要的结果,因为在DB中没有'额外的空间'.
为了完整起见,这也有效:
for ($i = 0; $i < $count; $i++) {
$where .= "'[[:<:]]${andkeywords[$i]}[[:>:]]' ";
}
Run Code Online (Sandbox Code Playgroud)
${blah}在字符串之外无效,但在插值字符串内部,它相当于$blah.
我原以为这种模式比其他答案更常见,但是......毕竟,你还想怎么打字"foo${var}bar"呢?显然"foo$var\bar"不起作用,因为\b是公认的逃脱序列.
在这种情况下的原因是"$ andkeywords [$ i] [[:>:]]"被解释为多维数组,并且:>:不是有效的数组索引.
我个人更喜欢Mykroft的方法,但你也可以通过逃避最终的开口括号来实现相同的结果:
$where=$where."'[[:<:]]$andkeywords[$i]\[[:>:]]' ";
Run Code Online (Sandbox Code Playgroud)
<Obligatory security moan>
请DBI为每个正则表达式值使用一个参数,而不是对其进行插值.为什么?
@andkeywords包含引号,反斜杠或特殊正则表达式字符,事情就会破裂.例如,关键字"O'Reilly"将导致数据库错误."'; drop database;"作为关键字输入.)这称为SQL注入攻击,并且网络充斥着对它们敏感的编码不良的网站.不要让你的其中之一.即使@andkeywords没有填写用户输入的数据,使用DBI参数几乎不需要额外的工作,并且您的代码可以安全地用于未来的未知环境.
</Obligatory security moan>