नाम दिया स्ट्रिंग प्रतिस्थापन?


13

मुझे अक्सर एक ही स्ट्रिंग के कई प्रतिस्थापन करना पड़ता है:

(format "%s %s %s" "a" "a" "a") ;; gives: "a a a"

(यह सिर्फ एक डमी उदाहरण है, इस मामले में व्हाट्सएप के साथ "ए" गोंद करना बेहतर है, लेकिन सामान्य तौर पर मैं अधिक जटिल स्थितियों से निपटता हूं)

क्या नामांकित प्रतिस्थापन बनाने का कोई तरीका है? अजगर में उदाहरण के लिए एक लिखना होगा:

"{0} {0} {0}".format("a") # or:
"{name} {name} {name}".format(name="a")


@ मलबारबा: मैंने उस धागे से कुछ उत्तर के संशोधित उत्तर को यहां उत्तर के रूप में पोस्ट किया है ।
Adobe

जवाबों:


16

इस उत्तर को फिर से लिखने से एक और समाधान मिलता है:

(format-spec "%a %a %a %b %b %b" (format-spec-make ?a "a" ?b "b"))

संपादित करें : एक और format-specसमाधान

जैसा कि मालाबार ने टिप्पणियों में एक और समाधान दिया है:

(format-spec "%a %a %a %b %b %b" '((?a . "a") (?b . "b")))

संपादित करें 2 : प्रतिस्थापन से पहले मूल्यांकन:

प्रतिस्थापन से पहले मूल्यांकन के साथ यहां उदाहरण हैं:

(let ( (a 1)
       (b 2) )
  (message (format-spec "a = %a; b = %b" (format-spec-make ?a a ?b b))) )
;; ⇒ a = 1; b = 1

(let ( (a 1)
       (b 2) )
  (message (format-spec "a = %a; b = %b" `((?a . ,a) (?b . ,b)))) )
;; ⇒ a = 1; b = 2

3
यह भी ध्यान दें कि format-spec-makeसिर्फ एक '((?a . "a") (?b . "b"))
मुलम्मा है

1
"संख्याओं के लिए काम नहीं करता है" - emacs.stackexchange.com/questions/7481/…
npostavs

@npostavs: बहुत अच्छा लगा! मैंने उत्तर संपादित किया।
Adobe

14

Magnar Sveen की स्ट्रिंग हेरफेर लाइब्रेरी s.el ऐसा करने के लिए कई तरह के तरीके प्रदान करती है। उदाहरण के लिए:

(require 's)
(s-format "${name} ${name} ${name}" 'aget '(("name" . "test")))
;; ==> "test test test"

ध्यान दें कि s-formatकिसी भी replacer समारोह ले जा सकते हैं, लेकिन के लिए विशेष हैंडलिंग प्रदान करता है aget, eltऔर gethash। तो आप टोकन की एक सूची का उपयोग कर सकते हैं और उन्हें सूचकांक द्वारा संदर्भित कर सकते हैं, जैसे:

(s-format "$0 $0 $0 $1 $1 $1" 'elt '("a" "b"))
;; ==> "a a a b b b"

आप इस तरह से इन-स्कोप वैरिएबल का उपयोग करके भी बदल सकते हैं:

(let ((name "test"))
  (s-lex-format "${name} ${name} ${name}"))
;; ==> "test test test"

1
बहुत बढ़िया, मैं इस सुविधा के बारे में नहीं जानता था! मैं sac का सबसे अधिक समय इस्तेमाल कर रहा हूं, बस एमएसीएस में आम स्ट्रिंग हेरफेर कार्यों को कैसे करें, लेकिन यह वास्तव में मौजूदा फ़ंक्शन के केवल एक-लाइन आवरण से अधिक है।
थामासा

3

s.el's s-lex-format वास्तव में वही है जो आप चाहते हैं, लेकिन यदि आप वास्तव में प्रतिस्थापन ब्लॉकों के अंदर कोड डालना चाहते हैं और न कि केवल चर नाम, मैंने इसे अवधारणा के प्रमाण के रूप में लिखा है।

(defmacro fmt (str)
  "Elisp string interpolation for any expression."
  (let ((exprs nil))
    (with-temp-buffer
      (insert str)
      (goto-char 1)
      (while (re-search-forward "#{" nil t 1)
        (let ((here (point))
              (emptyp (eql (char-after) ?})))
          (unless  emptyp (push (read (buffer-substring (point) (progn (forward-sexp 1) (point)))) exprs))
          (delete-region (- here 2) (progn (search-forward "}") (point)))
          (unless emptyp (insert "%s"))
          (ignore-errors (forward-char 1))))
      (append (list 'format (buffer-string)) (reverse exprs)))))

;; demo with variable and code substitution 
(fmt "My name is #{user-full-name}, I am running Emacs #{(if (display-graphic-p) \"with a GUI\" \"in a terminal\")}.")
;; results in
"My name is Jordon Biondo, I am running Emacs with a GUI."

यदि आप पागल हैं, तो आप fmtकॉल को दूसरे के अंदर भी एम्बेड कर सकते fmtहैं

(fmt "#{(fmt\"#{(fmt\\\"#{user-full-name}\\\")}\")}")
;; =>
"Jordon Biondo"

कोड केवल एक formatकॉल तक फैलता है इसलिए सभी प्रतिस्थापन क्रम में किए जाते हैं और रन समय पर मूल्यांकन किया जाता है।

(cl-prettyexpand '(fmt "Hello, I'm running Emacs #{emacs-version} on a #{system-type} machine with #{(length (window-list))} open windows."))

;; expands to

(format "Hello, I'm running Emacs %s on a %s machine with %s open windows."
        emacs-version
        system-type
        (length (window-list)))

हमेशा% s का उपयोग करने के बजाय प्रारूप प्रकार का उपयोग करने के साथ सुधार किया जा सकता है, लेकिन यह रनटाइम पर करना होगा और ओवरहेड को जोड़ना होगा, लेकिन फ़ंक्शन कॉल में सभी स्वरूप args के आसपास किया जा सकता है जो अच्छी तरह से स्वरूपित करता है चीजें अच्छी तरह से आधारित होती हैं प्रकार पर लेकिन वास्तव में एकमात्र परिदृश्य जहां आप चाहते हैं कि शायद तैरता है और आप प्रतिस्थापन में एक प्रारूप (% f "फ्लोट) भी कर सकते हैं, आप हताश थे।

यदि मैं इस पर अधिक काम करता हूं, तो मुझे इस उत्तर के बजाय इस जिस्ट को अपडेट करने की अधिक संभावना है। https://gist.github.com/jordonbiondo/c4e22b4289be130bc59b


3

सामान्य उद्देश्य नहीं है, लेकिन आपके मामले को हल करेगा:

(apply 'format "%s %s %s" (make-list 3 'a))

दिए गए उदाहरण का उपयोग करना:

(apply 'format (concat " * - :raw-html:`<img width=\"100%%\" "
                       "src=\"http://xxx.xxx/images/languages/"
                       "staff/%s.jpg\" alt=\"%s.jpg\"/>` - .. _%s:")
       (make-list 3 'some-image))

देता है:

" * - :raw-html:`<img width=\"100%\" src=\"http://xxx.xxx/images/languages/staff/some-image.jpg\" alt=\"some-image.jpg\"/>` - .. _some-image:"

यहाँ एक नमूना स्ट्रिंग मैं देख रहा हूँ: " * - :raw-html:`<img width=\"100%%\" src=\"http://xxx.xxx/images/languages/staff/%s.jpg\" alt=\"%s.jpg\"/>` - .. _%s:"- सभी %sसमान हैं।
Adobe

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