3

I want to convert

.waitForVisible('.someselector')
.click();

Into:

.waitAndClick('.someselector');

Automatically in a lot of files. So I wrote:

(defun hhaamm-replace-regexp-in-buffer (from to)
  (goto-char (point-min))
  (while (search-forward-regexp from nil t)
    (replace-match to nil nil))
  )

And I'm calling it in this way:

(hhaamm-replace-regexp-in-buffer "waitForVisible(.*)[\t
 ]*\.click()" "waitAndClick(\1)")

But I'm getting:

.waitAndClick(^A);

The expected result is:

.waitAndClick('.someselector');

Why the regexp group is not being replaced with the first matching group?

I also tried with \0 and it didn't work either.

  • 1
    You have to escape the backslash in strings, e.g., "waitAndClick(\\1)". – Tobias Apr 15 '16 at 18:06
4

The backslash character is special both in string literals (strings typed in Emacs Lisp, surrounded by double quotes) and in regular expressions as well as replacement specifications. Backslash followed by 1–3 octal digits stands for the character with this value, that's why you're seeing ^A (it's the character with the value 1).

Since you want the replacement specification

waitAndClick(\1)

you need to write it as a string literal as

"waitAndClick(\\1)"

i.e. surrounded by double quotes, and with a backslash before each backslash or double quote in the replacement specification.

Similarly your regular expression

waitForVisible(.*)[ 
 ]*\.click()

needs to have a backslash before the backslash character, otherwise the regexp contains . which matches any character (except a newline). Also you can make the Lisp source more readable by using the \n syntax instead of a literal newline inside the string. Furthermore your regexp doesn't contain a group; you wanted what's inside the parentheses, so put .* in a group:

"waitForVisible(\\(.*\\))[\t\n ]*\\.click()"

Your function seems to be reinventing dired-do-query-replace-regexp: open the directory containing the files, mark them (m to mark one file, % m to mark files whose name matches a regexp, etc.) and then press Q and enter the regexp and replacement.

  • If I try: (hhaamm-replace-regexp-in-buffer "waitForVisible(.*)[\t\n ]*\\.click()" "waitAndClick(\\1)") On: .waitForVisible(lalala)\n.click() I end with: .waitAndClick() – hhaamm Apr 15 '16 at 18:27
  • @hhaamm Ah, I hadn't paid attention to this one. \1 gives you nothing because there isn't any group in the regexp. I've edited my answer. – Gilles 'SO- stop being evil' Apr 15 '16 at 18:33
  • Ahh, true! I thought the groups only needed something like .* but it seems they need \(<something>\). It works now, thanks a lot! – hhaamm Apr 15 '16 at 18:36

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.