0

I intend to apply the split-string function to the following string

"\ghjky\dfsgi\45fdj\854f"

using the character "\" as a separator in order to get the list ("ghjky" "dfsgi" "45fdj" "854f").

I could use the following function

(split-string "\ghjky\dfsgi\45fdj\854f" "\" t)
;; return: forward-sexp: Scan error: "Unbalanced parentheses"

but it does not work, as the separator is not recognized

Then I try

(split-string "\ghjky\dfsgi\45fdj\854f" "\\" t)
;; return: split-string: Invalid regexp: "Trailing backslash"

but it still doesn't work

(split-string "\ghjky\dfsgi\45fdj\854f" "\\\\" t)
;; ("Ghjky^?fsgi%fdj854f")

Other attempts:

(defun split-now (astr)
    (interactive "sEnter a string: ")
    (split-string astr "\\\\" t))

(split-now "th\jki\fgt\y")
;; return: ("thjki^Lgty")

What is the correct procedure?

choroba
  • 1,925
  • 10
  • 16
  • @choroba has explained the correct procedure: To include a literal backslash in any double-quoted string in elisp code, you need to escape it with another backslash. `"\\"` is the string ``\``. Refer to `C-h i g (elisp)Syntax for Strings`. – phils Jun 12 '20 at 12:42
  • IOW, if you just do `M-x split-now` and you enter a string by typing at the prompt, you don't need to double the backslashes: you enter the string literally. But if you want to *evaluate the lisp code* `(split-now "")` then any backslashes that occur in `` must be doubled. So for you last example, you have to write `(split-now "th\\jki\\fgt\\y")`. – NickD Jun 12 '20 at 17:24

1 Answers1

2

Backslash is special in elisp strings, and even more special in regexes. You need to double it in double quoted strings (otherwise e.g. \4 is interpreted as C-d), and quadruple it in regexes to match literally:

(split-string "\\ghjky\\dfsgi\\45fdj\\854f" "\\\\" t)
; or
(split-string "\\ghjky\\dfsgi\\45fdj\\854f" (regexp-quote "\\") t)

The double backslashes are only needed when entering the string in double quotes literally in the code. After running this:

(call-interactively
 (lambda (string) "No doubling of backslashes needed"
   (interactive "s")
   (split-string string "\\\\" t)))

you can enter the string as is with single backslashes.

choroba
  • 1,925
  • 10
  • 16
  • You're right, but that system is not useful if the string is composed by the user at runtime and passed "as is" to the function. It is not possible to ask the user to learn elisp grammar to compose strings. – Acciaierie Stahlberg Jun 11 '20 at 19:04
  • 3
    @AcciaierieStahlberg: That's not how it works. This is how you represent the string in doulbe quotes, when reading it from outside, the special combinations aren't recognised. – choroba Jun 11 '20 at 19:08
  • @AcciaierieStahlberg: You are entering the string in double quotes again, so double backslashes are needed. Only when reading it from a file or interactively from the user, the string is entered literally. – choroba Jun 11 '20 at 19:20
  • It doesn't work. I added the code and the result into my question. – Acciaierie Stahlberg Jun 11 '20 at 19:28
  • @AcciaierieStahlberg: If you want to supply the string from code, you need to use double backslashes. If you want to let the user specify the string interactively, just pass the variable filled by the `interactive` and let the user enter the string literally. – choroba Jun 11 '20 at 20:05
  • The string contains just a single backslash. To represent a single backslash in elisp, you need to double it. `"\\"` is elisp syntax that represents the string containing a single backslash. – choroba Jun 11 '20 at 20:07
  • Just run `M-x split-now` and enter the string. – choroba Jun 11 '20 at 20:07