I've put together a function using the cl-ppcre package that escapes a string for insertion into a MySQL database. The function works perfectly, but I'd like to figure out why -- I had to place in more backslashes than I would have intuitively guessed. Since my head starts spinning when I try and track all the backslashes in escaping and de-escaping strings, I may have easily missed where some of them are disappearing to...
Code: Select all
(defun escape-string (string)
"Escape a string for MySQL, replacing a NUL byte with \0, a \ with \\, a '
with \' and a double quote with backslash double quote."
(let ((+null+ (code-char 0)))
(regex-replace-all
"\""
(regex-replace-all
"'"
(regex-replace-all
(string +null+)
(regex-replace-all "\\" string "\\\\\\")
"\\\\0")
"\\\\'")
"\\\"")))
Intuitively, I would have thought that "\\0" would be giving me \0, that only four backslashes would be necessary to escape the backslash, and that "\\'" would work for the single quote. However, it takes the above code to give the expected results:
Code: Select all
CL-USER> (format t (escape-string (string (code-char 0))))
\0
NIL
CL-USER> (format t (escape-string "\\"))
\\
NIL
CL-USER> (format t "~a~%" (escape-string "\"Hello, 'World!'\" \\"))
\"Hello, \'World!\'\" \\
NIL
Is the regex-replace-all function possibly eating up some of my backslashes, or where are they going to? Why not an extra pair of backslashes for the double quote since they were needed for everything else?
Thanks,
Jeremiah