cl-ppcre:regex-replace and backslashes in replacement

571 views Asked by At

May be this questions is really stuped, but I'm stuck. How can I put backslashes in cl-ppcre:regex-replace-all replacement?

For example I just want to escape some characters like ' " ( ) etc, so I'm going to do with | replacement first, to see that matching is ok:

    CL-USER> (princ (cl-ppcre:regex-replace-all "(['\\(\\)\"])"
"foo \"bar\" 'baz' (test)" "|\\1"))
    PRINTED: foo |"bar|" |'baz|' |(test|)

Ok, let's put slash:

    CL-USER> (princ (cl-ppcre:regex-replace-all "(['\\(\\)\"])"
"foo \"bar\" 'baz' (test)" "\\\1"))
    PRINTED: foo "bar" 'baz' (test) ;; No luck

No, we nedd two slashes:

    CL-USER> (princ (cl-ppcre:regex-replace-all "(['\\(\\)\"])"
"foo \"bar\" 'baz' (test)" "\\\\1"))
    PRINTED: foo \1bar\1 \1baz\1 \1test\1 ;; Got slash, but not \1

Maybe like this?

(princ (cl-ppcre:regex-replace-all "(['\\(\\)\"])"
"foo \"bar\" 'baz' (test)" "\\\{1}"))
PRINTED: foo "bar" 'baz' (test) ;; Nope, no luck here

Of course, if I'll put space between slashes everithing is ok, but I don't need it

(princ (cl-ppcre:regex-replace-all "(['\\(\\)\"])"
"foo \"bar\" 'baz' (test)" "\\ \\1"))
PRINTED: foo \ "bar\ " \ 'baz\ ' \ (test\ )

So, how can i write to get foo \"bar\" \'baz\' \(test\) printed? Thanks.

2

There are 2 answers

0
Joshua Taylor On BEST ANSWER

Six Source Slashes

CL-USER> (princ (cl-ppcre:regex-replace-all "(['\\(\\)\"])"
                                            "foo \"bar\" 'baz' (test)"
                                            "\\\\\\1"))
foo \"bar\" \'baz\' \(test\)

When you write the string in the source code, each slash is being used as an escape. You want the replacement text to be the sequence of characters \\1. To encode the first slash in the replacement (since CL-PPCRE is going to process slashes), CL-PPCRE needs to see the sequence of characters \\\1. The first two slashes encode the slash, and the third encodes the group number. To get that sequence of characters as a Lisp string, you have to write "\\\\\\1".

0
coredump On

Late answer, but for others, note that you would do well to avoid strings in such cases:

(cl-ppcre:regex-replace-all '(:register (:char-class #\' #\( #\) #\"))
                            "foo \"bar\" 'baz' (test)"
                            '("\\" 0))