Вот процедура, которая принимает строку, содержащую вывод midentify
, и возвращает список ассоциаций пар ключ-значение (что безопаснее, чем установка переменных Emacs в произвольном порядке). Он также имеет преимущество в том, что он разбирает числовые значения на фактические числа:
(require 'cl) ; for "loop"
(defun midentify-output-to-alist (str)
(setq str (replace-regexp-in-string "\n+" "\n" str))
(setq str (replace-regexp-in-string "\n+\\'" "" str))
(loop for index = 0 then (match-end 0)
while (string-match "^\\(?:\\([A-Z_]+\\)=\\(?:\\([0-9]+\\(?:\\.[0-9]+\\)?\\)\\|\\(.*\\)\\)\\|\\(.*\\)\\)\n?" str index)
if (match-string 4 str)
do (error "Invalid line: %s" (match-string 4 str))
collect (cons (match-string 1 str)
(if (match-string 2 str)
(string-to-number (match-string 2 str))
(match-string 3 str)))))
Вы бы использовали эту функцию так:
(setq alist (midentify-output-to-alist my-output))
(if (assoc "ID_LENGTH" alist)
(setq id-length (cdr (assoc "ID_LENGTH" alist)))
(error "Didn't find an ID_LENGTH!"))
РЕДАКТИРОВАТЬ: Модифицированная функция для правильной обработки пустых строк и завершающих строк.
Регулярное выражение действительно зверь; Регулярные выражения Emacs не известны своей легкостью на глазах. Чтобы разбить его немного:
- Внешний шаблон
^(?:valid-line)|(.*)
. Он пытается сопоставить действительную строку или же сопоставляет всю строку (.*
) в группе совпадений 4. Если (match-group 4 str)
не равно nil
, это указывает на то, что обнаружена неверная строка и возникла ошибка .
valid-line
- это (word)=(?:(number)|(.*))
. Если это соответствует, то часть имени пары имя-значение находится в строке соответствия 1, и если остальная часть строки соответствует номеру, то число находится в строке соответствия 2, в противном случае вся остальная часть строки в строке совпадений 3.