Сегодня на сайте Code Golf Stack Exchange я нашел этот ответ в Clojure на вопрос «Получить все ссылки на веб-странице».
(->> (slurp "http://www.stroustrup.com")
(re-seq #"(?:http://)?www(?:[./#\+-]\w*)+"))
Без модного макроса, это просто так:
(re-seq #"(?:http://)?www(?:[./#\+-]\w*)+" (slurp "http://www.stroustrup.com"))
Это возвращает список:
("http://www.morganstanley.com/" "http://www.cs.columbia.edu/" "http://www.cse.tamu.edu" ...)
Могу ли я сделать что-то подобное в Emacs Lisp?
Возможно, такая функция (re-seq regexp (buffer-string))
возвращает '(firstmatch secondmatch thirdmatch ...)
?
M-x occur
, что делает, но я бы заглянул внутрь для более низкоуровневых функций, чтобы сделать это.occur
. Мне придется просмотреть его источник.s.el
, но, может быть, есть еще что-то там. Здесь: github.com/magnars/s.el#s-match-strings-all-regex-string как насчет этого?Ответы:
Вот как вы можете сделать это на основе строк, как и просили.
источник
(re-seq "^.*$" "")
. Допустимое регулярное выражение, допустимая строка, но она никогда не заканчивается.Вероятно, стоит отметить, что вызов
occur
с универсальным аргументом заставляет его заполнять*Occur*
буфер только совпадениями - без имен файлов, номеров строк или информации заголовка. В сочетании с группой захвата это позволяет извлекать любой шаблон по желанию.Например,
C-u M-x occur
затем следует\"\(.*\)\"
запросить пользователя, для какой группы захвата собирать (по умолчанию\1
), а затем поместить содержимое каждой строки в кавычках в*Occur*
буфер.источник
У меня есть ответ от Emacs на этот вопрос: /codegolf//a/44319/18848
Используя ту же структуру (while (search) (print)), вы можете преобразовать ее в функцию, чтобы помещать совпадения из буфера в список и возвращать ее следующим образом:
источник
match-string
сmatch-string-no-properties
поэтому подсветка синтаксиса не извлекается. Возможно, вы захотите передатьregexp-group-index
использование, чтобы вы могли выбрать, какой текст будет сохранен. Так же как и обратный порядок поиска (текущий список указан первым). Посмотрите этот ответ, который включает в себя модифицированную версию emacs.stackexchange.com/a/38752/2418Использование
s.el
этого было бы короче, но, к сожалению, это дает слишком много совпадений:Если это нормально (регулярное выражение для URL в любом случае не идеально), это может быть просто короче, а если нет, то я не думаю, что смогу сделать его короче, чем ответ Алана Шутко.
источник
Позвольте мне упомянуть, почему я думаю, что это не реализовано в ядре. Просто по соображениям эффективности: нет необходимости копировать, создавать списки, передавать их и собирать мусор. Вместо этого сохраните всю строку в качестве буфера и оперируйте целочисленными границами соответствия. Вот как
occur
работает, например: он сопоставляет одну строку за раз и вставляет совпадение в*occur*
. Он не совпадает со всеми строками сразу, делает их в списке, делает цикл в списке для вставки*occur*
и собирает мусор в списке и его строках.Точно так же, как если бы вы не писали
(do (def x 1) (def x (+ 2 x)))
в Clojure, по умолчанию не следует пытаться заставить Elisp вести себя как функциональный язык. Я бы с удовольствием, если бы это было так, но мы должны отдать должное тому, что у нас есть на данный момент.источник
Если мне может быть разрешен плагин, взгляните на мою библиотеку "m-buffer".
Возвращает список маркеров для совпадений
foo
.источник