5

これは Emacs に関連しています: 大文字と小文字を変更するための正規表現の置換

私の追加の問題は、検索と置換をスクリプト化する必要があることですが、"\,()"ソリューションは (私にとっては) インタラクティブに使用した場合にのみ機能し(emacs 24.2.1)ます。\'スクリプト内では、「置換テキストでの使用が無効です」というエラーが表示されます。

私は通常、必要に応じてロードされるファイルに「実行置換」を書き込みます。次のようなもの:

(perform-replace "<\\([^>]+\\)>" "<\\,(downcase \1)>"tt nil 1 nil (point-min) (point-max))

関数を呼び出して replacement を生成することは可能(pg 741 of the emacs lisp manual)ですが、次の多くのバリエーションを試してみましたが、うまくいきませんでした:

(defun myfun ()
    (downcase (match-string 0)))

(perform-replace "..." (myfun . ()) t t nil)

誰でも助けることができますか?

4

2 に答える 2

3

のようなコンストラクト\,()は、へのインタラクティブな呼び出しでのみ許可さquery-replaceれます。これが、Emacs があなたのケースで文句を言う理由です。

のドキュメントでperform-replaceは、elisp コードで使用してはならないことが言及されており、次のコードを構築できるより良い代替案が提案されています。

(while (re-search-forward "<\\([^>]+\\)>" nil t)
  (replace-match (downcase (match-string 0)) t nil))

置換についてユーザーに対話的にクエリを実行したい場合は、使用したように使用perform-replaceするのがおそらく正しいことです。あなたのコードにはいくつかの異なる問題がありました:

  1. elisp のマニュアルに記載されているように、置換関数は 2 つの引数 (コンス セルに指定したデータと、既に行われた置換の数) を取る必要があります。

  2. のドキュメントquery-replace-regexp(またはelisp のマニュアル) に記載されているように、 case-fold-searchorcase-replaceが nil に設定されていることを確認して、大文字と小文字のパターンが置換に転送されないようにする必要があります。

  3. コンスセルを引用する必要があります(myfun . nil)。そうしないと、関数呼び出しとして解釈され、評価が早すぎます。

ここに作業バージョンがあります:

(let ((case-fold-search nil))
  (perform-replace "<\\([^>]+\\)>"
                   `(,(lambda (data count)
                       (downcase (match-string 0))))
                   t t nil))
于 2012-12-04T15:47:02.490 に答える
2

C-h f perform-replace言います:

Don't use this in your own program unless you want to query and set the mark
just as `query-replace' does.  Instead, write a simple loop like this:

  (while (re-search-forward "foo[ \t]+bar" nil t)
    (replace-match "foobar"))

ここで"<\\,(downcase \1)>"、 などの適切な文字列を作成する Elisp 式に置き換える必要があります(format "<%s>" (downcase (match-string 1)))

クエリなどが必要な場合は、次のことを試してください。C-M-% f\(o\)o RET bar \,(downcase \1) baz RET次にC-x RET RET、対話型呼び出し中にどの引数が構築されたかを確認します。

引数が (FUNCTION . ARGUMENT) の形式を取ることができることがわかります (関数のソース コードを表示するためにreplace.elクリックするとさらに良いでしょう)。より具体的には、コードには詳細を示すコメントが含まれています。C-h f perform-replacereplacements

;; REPLACEMENTS is either a string, a list of strings, or a cons cell
;; containing a function and its first argument.  The function is
;; called to generate each replacement like this:
;;   (funcall (car replacements) (cdr replacements) replace-count)
;; It must return a string.
于 2012-12-04T15:49:48.013 に答える