2013-01-07 30 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,但你不應該使用正則表達式,因爲這總是錯誤的。 –