2

See excerpt below for code used in emacs Cadence SKILL mode:

(cons (concat "\\<" (regexp-opt '("nil" "t") t)  "\\>")  'font-lock-constant-face)

it does a brilliant job at highlighting nil and t.
The issue is that if I have the string " nil_finder " anywhere within the code, it would highlight the part of the word which is "nil", and keep the _finder not highlighted. I want none of the " nil_finder " highlighted.
I have tried replacing the t with 'symbols or with 'words, and it did not work.
I can generate my own (many/ 1 huge) regular expression(s) to get the behavior that I need, but I read the regexp-opt returns a much more efficient regexp.
Thanks.

0

2 Answers 2

3

\< and \> match word boundaries.

Assuming _ is a symbol-constituent character in the buffer in question, you want to use \_< and \_> to match the beginning and end of the symbol.

See C-hig (elisp) Regexp Backslash

In rx syntax, these are symbol-start and symbol-end respectively.

4
  • Thanks. But isn't that what the second argument to regexp-opt should do? Oct 10, 2016 at 10:38
  • 1
    If you use 'symbols then yes, that will wrap the group with symbol boundaries.
    – phils
    Oct 10, 2016 at 10:59
  • 2
    Check (char-to-string (char-syntax ?_)) for that buffer. "_" means it's symbol-constituent.
    – phils
    Oct 10, 2016 at 11:02
  • Further to my previous comment, you would use M-: to enter that elisp expression in the buffer in question; but more simply you could use C-u C-x = with point over a _ character in the buffer in order to get detailed information, which would include the information: syntax: _ which means: symbol for a symbol-constituent character.
    – phils
    Aug 23, 2017 at 6:53
1
(require 's)  ;; All we need is `s-matches-p'
(require 'rx)

Your example:

(s-matches-p (concat "\\<" (regexp-opt '("nil" "t") t) "\\>") "nil_finder")
;; t

(s-matches-p (concat "\\<" (regexp-opt '("nil" "t") t) "\\>") "nil")
;; t

Fixed:

(s-matches-p
 (concat
  (rx symbol-start)
  (regexp-opt '("nil" "t") t)
  (rx symbol-end))
 "nil_finder")
;; nil

(s-matches-p
 (concat
  (rx symbol-start)
  (regexp-opt '("nil" "t") t)
  (rx symbol-end))
 "nil")
;; t

Better way:

(s-matches-p (rx symbol-start (or "nil" "t") symbol-end) "nil_finder")
;; nil

(s-matches-p (rx symbol-start (or "nil" "t") symbol-end) "nil")
;; t
1
  • 3
    (require 's) ;; All we need is `s-matches-p' - Or you could just use string-matches-p...
    – npostavs
    Aug 23, 2017 at 22:57

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.