続・with-temp-buffer

ふぅ。どーもどーも。


サイズが小さかったフリースが,すでに5回くらい「ビリッ」と悲鳴を上げていて,
あぁ,こりゃ XL を買わにゃならんなと,余分な1990円の出費に,
非常に悔しがっている whitypig です。
というか,L だときついよ。
でも!
嘆いていてもしょうがないので,今回のことをしっかり学習します。
なんせ,学習機能搭載型なので。

さて,with-temp-buffer の件です。

試行錯誤した結果あきらめる方向にしました。
なんちゅうか知らんけど,コンテキストみたいなんが変わると,
match-beginning は機能しないみたいです。
関数 f 内で関数 g を呼んで,g の中で string-match とかして,
g を抜け,f 内で match-beginning してもだめなご様子。

ほしいもの

要は,ケツから REGEXP の出現を調べたいだけ。
調べるときに,
(while (string-match-backward ...))
みたいに書ければかっくいいと思ったので,それを考えいました。

代替策

発想を切り替えて,ほなら,全部探してリストにして返せばいいんじゃね?
と思ったわけです。最後の出現がほしければ,(last l) すればいいだけじゃん?
というわけで,ジャン!。そんな大層なもんじゃないですけど。

(defun search-all-occurrances (regexp string)
  "Return the list of all ranges of REGEXP found in STRING.
A range is of pair like `(34 . 40).'
STRING 中での,REGEXP の出現場所を昇順でリストにして返す。
range は,`(開始位置 . 終了位置)' みたいなん。"
  (let (l (start 0))
    (with-temp-buffer
      (insert string)
      (while (string-match regexp string start)
        (push (cons (match-beginning 0) (match-end 0)) l)
        (setq start (match-end 0))))
    (reverse l)))

;; お試し企画
(let ((regexp "foo") (s "this foo is not the same as the foo appeared in that foo sentence.")
      ranges fooes)
  (search-all-occurrances regexp s))
=> ((5 . 8) (32 . 35) (53 . 56))

(let ((regexp "foo") (s "this foo is not the same as the foo appeared in that foo sentence.")
      ranges fooes)
  (setq ranges (search-all-occurrances regexp s))
  (dolist (elt ranges)
    (push (substring-no-properties s (car elt) (cdr elt)) fooes))
  fooes)
=> ("foo" "foo" "foo")

あとはこれを使うだけ

疲れたので,パスします。
なーんか主旨と違うところに注力している気がするなぁ(笑)
そうそう,push を覚えた!!