In normal regex, I would expect the following to be true:

(should (equal (string-match "^abc$\nx" "abc\nx ") 0))    ;; nope! nil
(should (equal (string-match "^abc\n$x" "abc\nx ") nil))
(should (equal (string-match "^abc\nx " "abc\nx ") 0))

However, the first one fails. Can someone please explain to me why this is the case? The only way I can make sense of it is that somehow the '$' is considered "on top of" the '\n', but that is very strange and I don't see it documented anywhere.

1 Answer 1


$ is matched only when it's used at the end of the regexp, or at the boundary of a grouping or alternative construct.

See (info "(elisp) Regexp Special") or Regexp-Special for more information.

  • Not entirely true. Both, the following forms return 0: (string-match "^abc\\($\\)\nx" "abc\nx ") and (string-match "^abc\\($\\|y\\)\nx" "abc\nx ") Please ensure completeness when citing the manual. (Emacs 28.1).
    – Tobias
    Sep 6, 2023 at 8:05
  • If I'm putting in a reference to the emacs manual, I don't see why I should copy exactly what it says. That's why the manual exists, after all :-)
    – rpluim
    Sep 6, 2023 at 14:05
  • Thanks, this mostly clarifies why it does not work then: the manual says it is for historical compatibility. But then I would agree that it's either a bug that I am successfully using it to match not at the end of the string in some cases, or the documentation is incorrect in saying that it cannot be used. Rather it should probably say the behavior is undefined when not at the end of a string, if this is intended.
    – Jared
    Sep 6, 2023 at 18:33
  • 1
    @rpluim The problem is that the statement becomes simply false and misleading by omitting the special cases. For an instance it is possible to match the empty string at the line end in the middle of the regexp just by grouping: \($\).
    – Tobias
    Sep 6, 2023 at 19:37
  • People who need to use the special cases should definitely read the manual, but whatever, I edited the answer.
    – rpluim
    Sep 7, 2023 at 7:33

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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