2013-01-07 90 views
3

我想逃避所有未被转义的双引号。如何避免彼此之间的报价?

我使用real_escape_string()了,但我想知道什么是错与后续的正则表达式/方法:

$str = '"Hello "" """ world!\"'; 
preg_replace('/(^|[^\\\\]{1})\"/', '${1}\"', $str); 

(PS:我知道 - \\”将不进行转义,并且可能在其他一些情况下一个问题,但这个不要紧,我的脚本)

结果是:

\"Hello \"" \""\" world!\"

但我想它是:

\"Hello \"\" \"\"\" world!\"
+5

对于一个SQL插入,你不应该在任何情况下推出你自己的转义**。改用参数化查询。 –

+0

这是一个糟糕的主意,但是你可以这样做的一个快速方法是:1)用一个未转义的引用替换所有的转义引号,然后2)用转义的引号替换所有未转义的引号:'str_replace (array('\'','''),array(''','''),$ str);' – nickb

+0

@WaleedKhan:谢谢你的建议,通常我不会。虽然在这种情况下,可能会弄乱任何东西的唯一字符是双引号 - 寻找一个快速解决方案。 –

回答

2

我认为你走在正确的轨道上,但你缺少两个关键要素。首先,你必须在反面字符中加上否定字符类别的引用:[^"\\]*。当该部分用完时,下一个字符(如果有的话)必须是是引用或反斜杠。

如果是反斜线,则\\.会消耗它和下一个字符,不管它是什么。它可能是一个引用,反斜杠或其他任何东西;你不在乎,因为你知道它已经逃脱了。然后你回到吞噬与[^"\\]*非特殊字符。

另一个缺失的元素是\G。它将第一个匹配定位到字符串的开头,就像\A。之后的每场比赛必须在前一场比赛结束时开始。这样,当正则表达式中的最后一个"发挥作用时,您知道它之前的每个角色都已经过检查,并且确实与未转义的引用相匹配。

$str = '"Hello "" """ world!\"'; 
$str = preg_replace('/\G([^"\\\\]*(?:\\\\.[^"\\\\]*)*)"/', '$1\"', $str); 
+0

谢谢!有效! :)老实说,我真的必须在我绝对明白之前多读几遍你的描述 - 这正是我所期待的!再次感谢! :) –

3

这里是你如何逃避你的SQL:

$str = mysql_real_escape_string($str); 

或:

$str = mysqli_real_escape_string($str); 

$str = *_real_escape_string($str); 
// * is your db extention 

或者你可以我们e PDO参数化您的输入。

+0

或“最佳” - 占位符! (但是,如果因为其他原因需要转义,这是* far * better:+1) – 2013-01-07 02:59:10

+0

谢谢 - 虽然我没有在寻找一种解决方案来转换SQL的字符串(使用mysqli解决方案btw),而是回答什么是关于我的正则表达式错了! :) –

+0

@PrinceCherusker,但你不应该使用正则表达式,因为这总是错误的。 –