নামকরণ স্ট্রিং প্রতিস্থাপন?


13

আমাকে প্রায়শই একই স্ট্রিংয়ের বেশ কয়েকটি প্রতিস্থাপন করতে হয়:

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

(এটি কেবল একটি ছদ্মবেশী উদাহরণ, এক্ষেত্রে একটি সাদা জায়গা দিয়ে "এ" আঠা দেওয়া ভাল তবে সাধারণভাবে আমি আরও জটিল পরিস্থিতি মোকাবিলা করি)

একটি নামক প্রতিস্থাপন করার উপায় আছে? উদাহরণস্বরূপ পাইথনে একজন লিখতে পারে:

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


@Malabarba: আমি কিছু উত্তর একটি পরিবর্তিত vestion যে থ্রেড থেকে এখানে একটি হিসেবে পোস্ট উত্তর
অ্যাডোব

উত্তর:


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

@ এনপোস্টাভস: জানতে পেরে দারুণ! আমি উত্তর সম্পাদনা করেছি।
অ্যাডোব

14

ম্যাগনার সোভেনের স্ট্রিং ম্যানিপুলেশন লাইব্রেরি 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
দুর্দান্ত, আমি এই বৈশিষ্ট্য সম্পর্কে জানতাম না! আমি বেশিরভাগ সময় ইল্যাক্সে সাধারণ স্ট্রিং ম্যানিপুলেশন কাজগুলি কীভাবে করবেন তা সন্ধান করার জন্য s.el ব্যবহার করেছি, তবে এটি বিদ্যমান ফাংশনের কেবলমাত্র এক-লাইনের মোড়কের চেয়ে বেশি।
ওয়াসামাস

3

s.el এর এস-লেক্স-ফর্ম্যাটটি আপনি যা চান তা হ'ল তবে আপনি যদি কেবল পরিবর্তনশীল নামগুলি না করে বিকল্পধারার ব্লকগুলির ভিতরে কোড রাখতে সক্ষম হন তবে আমি এটি ধারণার প্রমাণ হিসাবে লিখেছি।

(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 ব্যবহারের পরিবর্তে বিন্যাসের ধরণটি কীভাবে ব্যবহৃত হবে তা দিয়ে উন্নতি করা যেতে পারে, তবে এটি রানটাইমের সময় করতে হবে এবং ওভারহেড যুক্ত হবে তবে একটি ফাংশন কলের সমস্ত বিন্যাসের চারপাশে তৈরি করা যেতে পারে যা সুন্দরভাবে ভিত্তিতে জিনিসগুলি বিন্যাস করে টাইপ করুন তবে সত্যই একমাত্র দৃশ্য যেখানে আপনি চান এটি সম্ভবত ভাসমান এবং আপনি প্রতিস্থাপনে একটি (ফর্ম্যাট "% 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একই রকম all
অ্যাডোব

@ অ্যাডোব আমি আপনার উদাহরণ সহ উত্তরটি আপডেট করেছি।
wvxvw
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.