в emacs-lisp как правильно использовать replace-regexp-in-string - PullRequest
5 голосов
/ 04 февраля 2011

Учитывая строку, я хочу заменить все ссылки в ней описанием ссылки.Например, учитывая

this is a [[http://link][description]]

Я хотел бы вернуть

this is a description

Я использовал re-builder для построения этого регулярного выражения для ссылки:

\\[\\[[^\\[]+\\]\\[[^\\[]+\\]\\]

Thisмоя функция:

(defun flatten-string-with-links (string)
    (replace-regexp-in-string "\\[\\[[^\\[]+\\]\\[[^\\[]+\\]\\]"
                (lambda(s) (nth 2 (split-string s "[\]\[]+"))) string))

Вместо замены всей последовательности регулярных выражений она заменяет только завершающий "]]".Вот что он производит:

this is a [[http://link][descriptiondescription

Я не понимаю, что происходит не так.Любая помощь будет высоко ценится.

ОБНОВЛЕНИЕ : я улучшил регулярное выражение для ссылки.Это не имеет отношения к вопросу, но если кто-то собирается скопировать его, он также может получить лучшую версию.

1 Ответ

7 голосов
/ 04 февраля 2011

Ваша проблема в том, что split-string сгущает данные о совпадениях, которые replace-regexp-in-string полагается на неизменность, поскольку он собирается использовать эти данные о совпадении, чтобы решить, какие участки строки следует вырезать.Возможно, это ошибка документа в том, что replace-regexp-in-string не упоминает, что ваша замещающая функция должна сохранять данные соответствия.

Вы можете обойти это, используя save-match-data, который является макросом, предназначенным именно для этой цели:

(defun flatten-string-with-links (string)
    (replace-regexp-in-string "\\[\\[[a-zA-Z:%@/\.]+\\]\\[[a-zA-Z:%@/\.]+\\]\\]"
                (lambda (s) (save-match-data
                         (nth 2 (split-string s "[\]\[]+")))) string))
...