Чтобы подсчитать количество символов канала в текущей строке, попробуйте следующее:
(count-matches "|" (point-at-bol) (point-at-eol))
Чтобы проверить весь буфер, рассмотрите следующую функцию:
(require 'cl)
(defun invalid-points ()
(save-excursion
(goto-char (point-min))
(loop while (re-search-forward ".$" nil t)
unless (= 3 (count-matches "|" (point-at-bol) (point-at-eol)))
collect (point))))
, которая возвращаетсписок позиций строк, которые содержат недопустимое количество полей (поэтому вернет nil только тогда, когда весь буфер был действителен).
Для интерактивного использования, возможно, самый простой способ - использовать font-lock-modeвыделите недопустимые строки (или наоборот):
(font-lock-add-keywords
nil '(("^[^|\n]*\\(|[^|\n]*\\)\\{3\\}$" 0 highlight)))