我正在尝试从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中没有'额外的空间'。
答案 0 :(得分:7)
为了完整起见,这也有效:
for ($i = 0; $i < $count; $i++) {
$where .= "'[[:<:]]${andkeywords[$i]}[[:>:]]' ";
}
${blah}
在字符串之外无效,但在可插入字符串中,它等同于$blah
。
我原本以为这种模式比其他答案更常见,但是......毕竟,你还想怎么输入"foo${var}bar"
?显然"foo$var\bar"
不起作用,因为\b
是一个公认的转义序列。
答案 1 :(得分:6)
在这种情况下的原因是“$ andkeywords [$ i] [[:&gt;:]]”被解释为多维数组,并且:&gt;:不是有效的数组索引。
我个人更喜欢Mykroft的方法,但你也可以通过逃避最终的开口括号来实现相同的结果:
$where=$where."'[[:<:]]$andkeywords[$i]\[[:>:]]' ";
答案 2 :(得分:6)
<Obligatory security moan>
请为每个正则表达式值使用DBI
参数,而不是对其进行插值。为什么呢?
@andkeywords
的任何元素包含引号,反斜杠或特殊正则表达式字符,则事情将会中断。例如。关键字"O'Reilly"
将导致数据库错误。"'; drop database;"
作为关键字。)这称为SQL注入攻击,而网络 rife 包含编码较差的网站,这些网站容易受到攻击。不要让你的人成为其中之一。即使没有从用户输入的数据中填充@andkeywords
,也几乎不需要额外的努力来使用DBI参数,并且您的代码可以安全地用于未来的未知环境。
</Obligatory security moan>
答案 3 :(得分:2)
我从来没有真正相信像这样的字符串中的变量的自动重放。您可能需要考虑明确地执行您想要的连接:
for($i=0;$i<$count;$i++){
$where=$where . "'[[:<:]]" . $andkeywords[$i] . "[[:>:]]' ";
修改强> 正如ephemient所指出的那样,普遍接受的内联方式是
for($i=0;$i<$count;$i++){
$where=$where . "'[[:<:]]${andkeywords[$i]}[[:>:]]' ";
就我个人而言,我发现第一种方式更具可读性,但与所有事物一样,TIMTOWTDI
答案 4 :(得分:0)
如果您要包含任何错误消息的文本,将会很有帮助。
东西告诉我
for($i=0;$i<$count;$i++){
$where=$where . "'[[:<:]]" . $andkeywords[$i] . "[[:>:]]' ";
...
}
可以简化为
for (@andkeywords) {
$where .= qq('[[:<:]]${_}[[:>]]' );
...
}
或者
$where .= join ' ', map { qq('[[:<:]]${_}[[:>:]]') } @andkeywords;