Emacs: регулярное выражение, заменяющее регистр

Время от времени я хочу заменить все экземпляры значений, таких как:

<BarFoo>

с

<barfoo>

т.е. сделать регулярное выражение заменить все вещи в угловых скобках его строчными эквивалентами.

Кто-нибудь получил хороший фрагмент Lisp, который делает это? Можно с уверенностью предположить, что мы имеем дело только с ASCII-значениями. Бонусные баллы за все, что достаточно универсально, чтобы взять полное регулярное выражение, а не просто обрабатывать пример угловых скобок. Еще больше бонусных баллов за ответ, который просто использует M-x query-replace-regexp,

Спасибо,

Дом

3 ответа

Решение

Пытаться M-x query-replace-regexp с "<\([^>]+\)>" в качестве строки поиска и "<\,(downcase \1)>" в качестве замены.

Это должно работать для Emacs 22 и более поздних версий, см. Этот пост в блоге Стива Йегге для получения дополнительной информации о том, как выражения Lisp могут использоваться в строке замены.

Для более ранних версий Emacs вы можете попробовать что-то вроде этого:

(defun tags-to-lower-case ()
  (interactive)
  (save-excursion
    (goto-char (point-min))
    (while (re-search-forward "<[^>]+>" nil t)
      (replace-match (downcase (match-string 0)) t))))

Я понимаю, что это древний вопрос, но я только что обнаружил, как это сделать в Emacs до версии 22 (моя версия - 21.3.1) без необходимости определять пользовательскую функцию Lisp: используйте M-x query-replace-regexp-eval(упоминается в верхней части этой вики-страницы Emacs ) с <\([^>]+\)> как строка поиска и (concat "<" (downcase \1) ">") в качестве замены.

Это должно работать с любой заменяющей строкой, которая может быть определена как объединение частей, включая захваченные группы, не измененные какой-либо функцией. Например:

      <BarFoo baz="Quux">

может иметь только имя тега в нижнем регистре:

      <barfoo baz="Quux">

используя строку поиска <\([A-Za-z]+\)\([^>]*\)> и замена (concat "<" (downcase \1) \2 ">") (который также работает на примере OP, который выглядит как тег без атрибутов).

Используя зло, вы можете просто сделать :%s/<\([^>]+\)>/<\L\1>

\L отвечает за нижний регистр всех следующих букв, это также должно работать для query-replace-regexp.

Я не нашел документации по Emacs для этого, но, похоже, она соответствует этому списку: https://www.boost.org/doc/libs/1_44_0/libs/regex/doc/html/boost_regex/format/perl_format.html

Другие вопросы по тегам