@peccul is peccu

(love peccu '(emacs lisp cat outdoor bicycle mac linux coffee))

= Emacsでreplace-regexp(C-M-%)を使う時にLisp式を使える

[2010-09-01 03:09:24]
>>>[emacs]

矩形選択した時に連番を挿入したい.そのための布石

参考:cua-modeで矩形選択した部分に連番を挿入する

replace-regexpで置換文字列にLisp式を書けるらしい(from ZDNet JP)

ので,replace-regexpのドキュメントをえせ翻訳してみた.
参考程度にどうぞ.

replace-regexp は replace.elで定義されている関数.次のは引数

  (replace-regexp regexp to-string &optional delimited start end)


regexpにマッチした文字列をto-stringに置き換える
変数case-replaceと変数case-fold-searchがnon-nilで,regexpに大文字がなかったら,大文字小文字を保持する.


transient-mark-mode中ではマークが有効ならそのマークされている範囲内で置換する.
transient-mark-modeじゃなかったらカーソル位置からバッファの最後まで


3番目の引数delimited(M-xで呼び出してる時は数値引数で渡される(C-u 数字))がnon-nilならその単語の境界で囲まれてる範囲でマッチしたものだけ置換する.
4番目と5番目のstartとendは置換するリージョンを指定する


to-stringでは\&がregexpでマッチした全体になり,\N(Nは整数)はregexp中のN番目の\(..\)にマッチしたものになる.
\?はマッチした部分を置換する時に毎回ミニバッファで置換文字列を聞いてくる.


M-xで呼び出されたとき\,に続けてLispの式を置換文字列に使うことができる.その式中で\&はマッチした全体になり,\Nは部分マッチしたもの(N番目の\(..\))になる.
\#&と\#Nは文字列を数値とみなして扱う(string-to-numberを通されるみたいなの).\#は何番目のreplace-countかをあらわす.(置換する時にyと答えた分のカウント.0始まり)


もしLisp式が識別子とその次の文字で,置換文字列ではその一部とみなされるなら,\,か\#でラップできる.
ついでに言うと,この特別なケースでは\#を直接書くことができる(\,つけてLisp式にしなくても)


Lisp式の機能をM-xから呼び出した時に使うときは,to-stringは文字列の変わりにlistに作り替えられる.
C-x M-: (repeat-complex-command)で実際にどんなlistが作られたのか確認することができる.


query-replace-interactiveがnon-nilなら最後に実行したインクリメンタルサーチregexpに使われるので,ミニバッファでそれを入れる必要が無くなる.


この関数名(replace-regexp)をLispプログラムで使うことは間違い.loopで以下のように書かれるべき.

(while (re-search-forward regexp nil t)
  (replace-match to-string nil nil))

こっちの方が速くてマークしたり何かをprintしたりしない.

以上.

ちなみに,usage-memo.el

(auto-install-from-emacswiki "usage-memo.el");; <eval here!>

をつかって,私の環境ではdescribe-functionしたらこの えせ邦訳が表示されるのだ.

以下全文

間違ってたりあれば教えてくださるとありがたいです

replace-regexp is an interactive compiled Lisp function in `replace.el'.
(replace-regexp regexp to-string &optional delimited start end)

Replace things after point matching regexp with to-string.
Preserve case in each match if `case-replace' and `case-fold-search'
are non-nil and regexp has no uppercase letters.

In Transient Mark mode, if the mark is active, operate on the contents
of the region. Otherwise, operate from point to the end of the buffer.

Third arg delimited (prefix arg if interactive), if non-nil, means replace
only matches surrounded by word boundaries.
Fourth and fifth arg start and end specify the region to operate on.

In to-string, `\&' stands for whatever matched the whole of regexp,
and `\N' (where N is a digit) stands for
whatever what matched the Nth `\(...\)' in regexp.
`\?' lets you edit the replacement text in the minibuffer
at the given position for each replacement.

In interactive calls, the replacement text may contain `\,'
followed by a Lisp expression used as part of the replacement
text. Inside of that expression, `\&' is a string denoting the
whole match, `\N' a partial match, `\#&' and `\#N' the respective
numeric values from `string-to-number', and `\#' itself for
`replace-count', the number of replacements occurred so far.

If your Lisp expression is an identifier and the next letter in
the replacement string would be interpreted as part of it, you
can wrap it with an expression like `\,(or \#)'. Incidentally,
for this particular case you may also enter `\#' in the
replacement text directly.

When using those Lisp features interactively in the replacement
text, to-string is actually made a list instead of a string.
Use C-x M-: after this command for details.

If `query-replace-interactive' is non-nil, the last incremental search
regexp is used as regexp--you don't have to specify it with the minibuffer.

This function is usually the wrong thing to use in a Lisp program.
What you probably want is a loop like this:
(while (re-search-forward regexp nil t)
(replace-match to-string nil nil))
which will run faster and will not set the mark or print anything.