I guess you want a two-pass system then, whereby you firstly collect/count identifiers, and secondly discard those which appeared more than once, and then highlight what's left.
Here's one approach...
(defun my-highlight-unique-symbols ()
"In each block, highlight all symbols which occur exactly once."
(interactive)
(font-lock-ensure)
(save-excursion
(goto-char (point-min))
(let ((regexp "\\_<.+?\\_>")
(case-fold-search nil)
(blockstart (point))
(blockdelimiter "\n\n\n"))
;; Establish the next block.
(while (and (not (eobp))
(or (search-forward blockdelimiter nil t)
(goto-char (point-max))))
(let ((blockend (point))
(identifiers (obarray-make)))
(goto-char blockstart)
(while (re-search-forward regexp blockend t)
;; Have we seen this identifier before?
(let* ((sym (intern (match-string 0) identifiers))
(seen (get sym 'region)))
(if seen
;; Mark it as a duplicate.
(unless (eq seen 'duplicate)
(put sym 'region 'duplicate))
;; This is the first time we've seen this identifier.
;; Store the region boundaries for the match.
(put sym 'region (cons (match-beginning 0)
(match-end 0))))))
;; Highlight the unique instances.
(with-silent-modifications
(obarray-map
(lambda (sym)
(let ((region (get sym 'region)))
(unless (eq region 'duplicate)
(put-text-property (car region) (cdr region)
'face 'highlight))))
identifiers))
;; Prepare for the next block.
(setq blockstart blockend)
(goto-char blockstart))))))
Which you can run with M-x my-highlight-unique-symbols
This version is not a permanent effect -- you can run it to highlight things, but subsequent edits to the buffer will likely cause font-lock to update the faces for that text, and clobber this highlighting.
If you don't edit the buffer, then I'm fairly sure that font-lock won't subsequently/stealthily fontify/clobber any of the highlight faces, as I've called font-lock-ensure
up front; so calling this command should be good enough for read-only purposes.
foo bar foo baz
you want onlybar
andbaz
to be highlighted?