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