1

しばらく前に、@Oleg Pavliv がhttps://unix.stackexchange.com/questions/47615/emacs-simple-arithmetics-in-query-replaceで、emacs で (対話的に) クエリ置換で単純な算術演算を行う方法を説明しました。

小さな elisp プログラムに同じ方法を使用したいのですが、うまくいきません。たとえば、次の elisp コードの最小限の例を考えてみましょう。

(defun Nshift ()
(interactive)
(query-replace-regexp "\\([0-9]+\\)\\.Number" "\\,((+ 3 \\#1)).Number")
)

Nshiftたとえば、文字列を含むバッファーで実行すると4.Number、次のエラーメッセージが表示されます。

match-substitute-replacement: Invalid use of `\' in replacement text

の正しい elisp 実装はNshiftどのようになりますか?

編集:

ショーンズの回答が、簡単で読みやすい構文でより複雑な置換 (アプリケーションで必要な) に一般化される方法がわからないため、たとえば、次のものと同等の正しい (そして読みやすい) ものは何でしょうか?

(query-replace-regexp "\\([0-9]+\\)\\.Number.\\([0-9]+\\)" "\\,((+ 3 \\#1)).Number.\\,((+ 8 \\#2))")
4

1 に答える 1

2

このような:

(defun Nshift ()
  (interactive)
  (while (search-forward-regexp "\\([0-9]+\\)\\.Number" nil t)
    (replace-match (format "%s.Number" (+ 3 (string-to-number (match-string 1)))))))

追加するために編集:

拡張された例は、次のように実装できます。

(defun Nshift ()
  (interactive)
  (while (search-forward-regexp "\\([0-9]+\\)\\.Number\\.\\([0-9]+\\)" nil t)
    (replace-match
     (number-to-string (+ 3 (string-to-number (match-string 1))))
     nil nil nil 1)
    (replace-match
     (number-to-string (+ 8 (string-to-number (match-string 2))))
     nil nil nil 2)))

replace-match単一の部分式だけを置き換えるオプションの5番目の引数があり、置換テキストで固定テキスト( ".Number。")を複製する必要がないため、元のソリューションよりも実際にはさらに簡単です。

ここで実行できるリファクタリングがいくつかあります。

(defun increment-match-string (match-index increment)
  (replace-match
   (number-to-string (+ increment (string-to-number (match-string match-index))))
   nil nil nil match-index))

次に、Nshiftは次のように実装できます。

(defun Nshift ()
  (interactive)
  (while (search-forward-regexp "\\([0-9]+\\)\\.Number\\.\\([0-9]+\\)" nil t)
    (increment-match-string 1 3)
    (increment-match-string 2 8)))
于 2012-12-13T19:40:12.557 に答える