Na stronie Code Golf Stack Exchange znalazłem dziś odpowiedź w Clojure na pytanie „Uzyskaj wszystkie linki na stronie internetowej”.
(->> (slurp "http://www.stroustrup.com")
(re-seq #"(?:http://)?www(?:[./#\+-]\w*)+"))
Bez fantazyjnego makra jest to tylko:
(re-seq #"(?:http://)?www(?:[./#\+-]\w*)+" (slurp "http://www.stroustrup.com"))
To zwraca listę:
("http://www.morganstanley.com/" "http://www.cs.columbia.edu/" "http://www.cse.tamu.edu" ...)
Czy mogę zrobić coś podobnego w Emacs Lisp?
Być może funkcja taka (re-seq regexp (buffer-string))
zwraca '(firstmatch secondmatch thirdmatch ...)
?
elisp
regular-expressions
niania
źródło
źródło
M-x occur
działa, ale zajrzałbym do wnętrza, aby znaleźć więcej funkcji niskiego poziomu.occur
. Będę musiał przejrzeć jego źródło.s.el
, ale może jest ich więcej. Tutaj: github.com/magnars/s.el#s-match-strings-all-regex-string a co z tym?Odpowiedzi:
Oto, jak możesz to zrobić na podstawie ciągów, zgodnie z żądaniem.
źródło
(re-seq "^.*$" "")
. Poprawne wyrażenie regularne, poprawny ciąg, ale nigdy się nie kończy.Prawdopodobnie warto zauważyć, że wywołanie
occur
argumentem uniwersalnym powoduje, że zapełnia on*Occur*
bufor tylko dopasowaniami - bez nazw plików, numerów linii ani informacji nagłówka. W połączeniu z grupą przechwytującą pozwala to wyodrębnić dowolny wzór.Na przykład,
C-u M-x occur
po którym\"\(.*\)\"
pojawi się monit o wybór grupy przechwytywania (ustawienie domyślne\1
), a następnie umieszczenie zawartości każdego cytowanego ciągu w*Occur*
buforze.źródło
Mam odpowiedź emacs lisp na to pytanie: /codegolf//a/44319/18848
Korzystając z tej samej struktury (while (szukaj) (drukuj)), możesz ją zmodyfikować w funkcję, aby wypychać dopasowania z bufora do listy i zwracać w następujący sposób:
źródło
match-string
sięmatch-string-no-properties
więc punktem kulminacyjnym składnia nie jest pobierany. Możesz przekazaćregexp-group-index
do użycia, abyś mógł wybrać, który tekst ma być przechowywany. Oprócz odwrócenia kolejności wyszukiwania (aktualna lista jest ostatnia do pierwszej). Zobacz tę odpowiedź, która obejmuje zmodyfikowaną wersję emacs.stackexchange.com/a/38752/2418Korzystanie z
s.el
tego byłoby krótsze, ale niestety daje zbyt wiele dopasowań:Jeśli to jest w porządku (wyrażenie regularne dla adresów URL i tak nie jest idealne), może to być po prostu krótsze, a jeśli nie, to nie sądzę, żebym mógł go skrócić niż odpowiedź Alana Shutko.
źródło
Pozwól mi tylko wspomnieć, dlaczego uważam, że nie jest to zaimplementowane w rdzeniu. Po prostu ze względu na wydajność: nie trzeba kopiować, tworzyć list, przekazywać ich i wyrzucać śmieci. Zamiast tego przechowuj cały ciąg jako bufor i działaj z granicami dopasowania liczb całkowitych. Tak
occur
działa na przykład: dopasowuje jeden ciąg naraz i wstawia dopasowanie do*occur*
. Nie pasuje do wszystkich ciągów naraz, umieszcza je na liście, zapętla listę, aby ją wstawić,*occur*
a śmieci zbierają listę i jej ciągi.Tak jak nie piszesz
(do (def x 1) (def x (+ 2 x)))
w Clojure, nie powinieneś domyślnie starać się, aby Elisp zachowywał się jak język funkcjonalny. Chciałbym, gdyby tak było, ale musimy zrobić to, co mamy w tej chwili.źródło
Jeśli mogę otrzymać wtyczkę, spójrz na moją bibliotekę „m-buffer”.
Zwraca listę znaczników do dopasowań
foo
.źródło