एक सूची के रूप में बफर में सभी regexp मैच प्राप्त करें


18

कोड गोल्फ स्टैक एक्सचेंज साइट पर आज, मैंने पाया इस उत्तर सवाल "एक वेबपृष्ठ पर सभी लिंक प्राप्त करने के लिए" 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है, लेकिन मैं ऐसा करने के लिए अधिक निम्न-स्तरीय कार्यों के लिए अंदर देखूंगा।
wvxvw

@wvxvw यह एक अच्छी बात है, मैंने इसके बारे में सोचा भी नहीं था occur। मुझे इसके स्रोत को देखना होगा।
नानी

मैंने अंदर देखा, और ओह, हाय, यह कोड बहुत अधिक है और इसे पुन: प्रस्तुत करना आसान नहीं है, बिल्कुल नहीं। मेरा अगला उम्मीदवार होगा s.el, लेकिन शायद वहाँ अधिक है। यहाँ: github.com/magnars/s.el#s-match-strings-all-regex-string इस बारे में कैसे?
wvxvw

जवाबों:


16

यहां बताया गया है कि अनुरोध के अनुसार आप इसे स्ट्रिंग्स के आधार पर कैसे कर सकते हैं।

(defun re-seq (regexp string)
  "Get a list of all regexp matches in a string"
  (save-match-data
    (let ((pos 0)
          matches)
      (while (string-match regexp string pos)
        (push (match-string 0 string) matches)
        (setq pos (match-end 0)))
      matches)))

; Sample URL
(setq urlreg "\\(?:http://\\)?www\\(?:[./#\+-]\\w*\\)+")
; Sample invocation
(re-seq urlreg (buffer-string))

यह पूरी तरह से नहीं दिखता है, क्या आप इसे पूरी तरह से काम करने वाले उत्तर में विस्तारित कर सकते हैं?
वामासा

1
कोड पूरा था, लेकिन मैंने उपयोग का एक उदाहरण भी जोड़ा। आप और क्या देखना चाहेंगे?
एलन शटको

1
यह समाधान बहुत सरल है, दुर्भाग्य से। कोशिश करो (re-seq "^.*$" "")। वैध रेगेक्सप, वैध स्ट्रिंग, लेकिन यह कभी भी समाप्त नहीं होता है।
फिल लॉर्ड

8

यह शायद ध्यान देने योग्य है कि लागू है occurसार्वभौमिक तर्क के साथ का कारण बनता है यह पॉप्युलेट करने के लिए*Occur* बफर को केवल मैचों के साथ - कोई फ़ाइल नाम, लाइन नंबर या हेडर जानकारी नहीं। जब एक कैप्चर समूह के साथ संयुक्त, यह जो कुछ पैटर्न वांछित है निकालने के लिए एक की अनुमति देता है।

उदाहरण के लिए, C-u M-x occurइसके बाद \"\(.*\)\"उपयोगकर्ता को संकेत मिलेगा जिसके लिए समूह को इकट्ठा करने के लिए (डिफ़ॉल्ट \1), और फिर प्रत्येक उद्धृत स्ट्रिंग की सामग्री को *Occur*बफर में रखें।


6

मेरे पास उस प्रश्न का एक इमैक लिस्प उत्तर है जो पोस्ट किया गया है: /codegolf//a/44319/18848

उसी (समय (खोज) (प्रिंट)) संरचना का उपयोग करके आप किसी फ़ंक्शन को किसी बफ़र में मैचों को सूची में धकेलने और उसे इस तरह वापस करने के लिए इसे संशोधित कर सकते हैं:

(defun matches-in-buffer (regexp &optional buffer)
  "return a list of matches of REGEXP in BUFFER or the current buffer if not given."
  (let ((matches))
    (save-match-data
      (save-excursion
        (with-current-buffer (or buffer (current-buffer))
          (save-restriction
            (widen)
            (goto-char 1)
            (while (search-forward-regexp regexp nil t 1)
              (push (match-string 0) matches)))))
      matches)))

अच्छा जवाब है, टिप्पणी आप को बदलने के लिए चाहते हो सकता है match-stringके साथ match-string-no-propertiesइतना वाक्य रचना उजागर निकाला नहीं है। आप regexp-group-indexउपयोग करने के लिए एक पास करना चाहते हैं ताकि आप चुन सकें कि कौन सा पाठ संग्रहीत है। साथ ही खोज के आदेश को पलटने के रूप में (वर्तमान सूची पिछले करने वाली पहली है)। इस जवाब जो एक संशोधित संस्करण शामिल देखें emacs.stackexchange.com/a/38752/2418
ideasman42

3

का उपयोग करते हुए s.elइस छोटे किया गया है होगा, लेकिन, दुर्भाग्य से, यह भी कई मैचों देता है:

(defun all-urls-in-buffer ()
  (s-match-strings-all
   "\\(?:http://\\)?www\\(?:[./#+-]\\w*\\)+"
   (buffer-string)))

यदि यह ठीक है (URL के लिए regex वैसे भी सही नहीं है), यह सिर्फ छोटा हो सकता है, और यदि नहीं, तो मुझे नहीं लगता कि मैं इसे एलन शटको के जवाब से कम कर सकता हूं।


2

मुझे केवल इस बात का उल्लेख करना चाहिए कि मुझे क्यों लगता है कि यह कोर में लागू नहीं है। बस दक्षता कारणों के लिए: प्रतिलिपि बनाने, सूची बनाने, उन्हें पास करने और कचरा इकट्ठा करने की कोई आवश्यकता नहीं है। इसके बजाय, पूरे स्ट्रिंग को बफर के रूप में संग्रहीत करें, और पूर्णांक मैच सीमा के साथ काम करें। occurउदाहरण के लिए, यह कैसे काम करता है: यह एक समय में एक स्ट्रिंग से मेल खाता है और मैच को सम्मिलित करता है *occur*। यह एक बार में सभी तार से मेल नहीं खाता, उन्हें सूची में बनाने के लिए, सूची में पाश में डालने के लिए *occur*और कचरा सूची और उसके तार इकट्ठा।

ठीक वैसे ही जैसे आप (do (def x 1) (def x (+ 2 x)))क्लोजर में नहीं लिखेंगे , आपको डिफ़ॉल्ट रूप से एलीस्प को एक कार्यात्मक भाषा की तरह व्यवहार करने की कोशिश नहीं करनी चाहिए। अगर यह होता तो मुझे बहुत अच्छा लगता, लेकिन इस समय जो हमें मिला है, उसके साथ हमें बनाना है।


1

अगर मुझे प्लग की अनुमति दी जा सकती है, तो मेरी "एम-बफर" लाइब्रेरी पर एक नज़र डालें।

(m-buffer-match buffer "foo")

करने के लिए मैच के लिए मार्कर की एक सूची देता है foo

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.