0

I have a function which returns a file path, but the returned value has backslash excaped 'special' characters e.g.

"/home/fred/Documents/This\ file\ \(20200120\).txt"

but the function where I want to use this value does not handle the string escaping and just wants the plain filename string i.e.

"/home/fred/Documents/This file (20200120).txt"

What would be the canonical way to do this in elisp?

My quick and dirty solution (which seems to work) is a simple function

(defun tx-parse-path (p)
  (concat (reduce #'(lambda (acc l)
                      (if (not (= ?\\ l))
                          (cons l acc)
                        acc))
                  (reverse p)
                  :initial-value '())))

I suspect there is some built-in function, but have not found it. I don't need to worry about win32 compatibility (only use GNU Linux and macOS) and of course, the flaw with the brute force solution above is that it will strip legitimate '\' from a filename.

  • Can you give us some details about the first function -- the one which returns the escaped string? How is that value generated? – phils Jan 24 at 8:47
  • An alternative solution would be adjusting the function you obtain the path from to not insert backslashes. – wasamasa Jan 24 at 12:00
  • I haven't dissected the code yet. The value actually comes from string property value. I've not yet gone into the code which generates the value and puts it into the string property. This isn't my code - it is part of a package I'm using which fails when the path name is used because of the 'escaped' characters. – Tim X Jan 24 at 12:04
  • Changing the function which generates the escaped value is not a preferred approach. This is not my code and I don't want to have to go through all the ways it is used to verify such changes won't have other unforeseen consequences. – Tim X Jan 24 at 12:06
  • You will need to establish how the escaped value was generated in the first place, so that you can confirm what the rules for reversing it are. For example, shell-quote-argument might do more than just add backslashes, depending on the input. – phils Jan 24 at 13:53
1

You could simply say:

(replace-regexp-in-string "\\\\\\(.\\|\n\\)" "\\1" STRING)

Or equivalently:

(replace-regexp-in-string (rx "\\" (group anything)) "\\1" STRING)
| improve this answer | |
  • Yes, that was my first thought as well and probably where I would have gone eventually. To be honest, while I'm very comfortable with regexp in general, I tend to avoid them in elsip due to the backslashing required (though things like 'rx' does make that easier - which I forget about) – Tim X Jan 24 at 12:08
  • I really wanted to check there wasn't something already defined as I thought this might have been something common enough that it was already there, but using a name I wasn't searching for and had not found. – Tim X Jan 24 at 12:09
  • 1
    I don't think it's a very common thing to want to do -- if a value is escaped then it's generally destined only for processing by something else -- and the transformation used will be particular to the something else in question, so you need to know that process in order to reverse it. – phils Jan 24 at 14:12

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.