11

I need to perform regex query replace, such that

foo in foo bar is matched, but foo in foo baz is not. Normally I would use regex look ahead, e.g. foo(?=bar).

However, it seems like Emacs cannot do this? Vim seems capable, but evil mode in spacemacs cannot.

10

No, Emacs regular expressions do not support arbitrary zero-width look-ahead/behind assertions.

n.b. Evil and Spacemacs (like all elisp libraries) are irrelevant when it comes to questions about the Emacs Lisp language implementation.

  • So is it impossible to replace foo in foobar but not in foobaz? This is a common enough operation that I thought there must be a solution. Perhaps looking ahead and behind is the wrong approach? – Heisenberg May 14 '17 at 7:36
  • This isn't strictly equivalent, but replacing foo\(bar\) with baz\1 will be sufficient in all cases where bar didn't contain further matches. – phils May 14 '17 at 8:37
  • If you're writing elisp, you have lots of flexibility, and if you're replacing interactively you can invoke arbitrary elisp during replacements, so ultimately there are ways to do these things. Just not as conveniently as you might do with those assertions. – phils May 14 '17 at 8:41
  • e.g.: replacing foo with \,(if (looking-at "bar") "baz" \&) will replace foo with baz if the following text is bar (and replace foo with foo otherwise). Which still isn't the same thing as only matching foo when it's followed by bar, but it's another option. – phils May 14 '17 at 8:48
  • I guess this is like what you said above, but it seems like you can type: C-S-M-% foo \(bar\) RET FOO \1 RET to replace all foo bar with FOO bar, but leave all foo baz alone. Is this missing some thing you wanted? – John Kitchin May 14 '17 at 16:09

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.