探しま〜す。解決編。

どもども。

trotr さんからトラックバックいただきました。
まちゃあき風に言うと,星3つです!
ありがとう,trotr さん!
http://d.hatena.ne.jp/trotr/20091103/1257247845


というわけで,trotr さんのを参考にして,書いてみました。
ちなみに,with-temp-buffer は初・体・験。うふ。
んで,ちょっとおためしをば。
確かに,re-search-backward すると,マッチした文字列の最初の文字上にポイントがくるので,
そこは,ナイーブに? 1- する方向で。

(defun string-match-backward (regexp string &optional start)
  (with-temp-buffer
    (insert string)
    (goto-char (or start (point-max)))
    (if (re-search-backward regexp nil t)
        (match-beginning 0)
      nil)))

(let ((s "This is a foo that is not same as the foo appeared in that sentence written by foo.")
      (start nil))
  (string-match-backward "foo" s)
  (setq start (match-beginning 0))
  (substring-no-properties s (if (zerop start) start (1- start))))
=> "foo."

(let ((s "This is a foo that is not same as the foo appeared in that sentence written by foo.")
      (start nil))
  (string-match-backward "foo" s)
  (setq start (match-beginning 0))
  (string-match-backward "foo" s start)
  (setq start (match-beginning 0))
  (substring-no-properties s (if (zerop start) start (1- start))))
=> "foo appeared in that sentence written by foo."

(let ((s "This is a foo that is not same as the foo appeared in that sentence written by foo.")
      (start nil))
  (string-match-backward "foo" s)
  (setq start (match-beginning 0))
  (string-match-backward "foo" s start)
  (setq start (match-beginning 0))
  (string-match-backward "foo" s start)
  (setq start (match-beginning 0))
  (string-match-backward "foo" s start))
=> nil ; foo は3つしかないので,4つめを探そうとすると,nil が返る。よしよし。

とりあえず,期待した結果になるようです。


さて,これを使って何をしようとしているのかというと・・・。
もったいぶっている割には大したこたーないです。
単語復習プログラムでバグを見つけて,2語以上の熟語を,`()' に置換するばやいに,
失敗するというものでありまして。
たとえば,xxx xxx a tricle of xxx xx that xxx a floodtide of xxx.
みたいな文があったときに,この,a tricle of を探したいという。
この場合は,"a tricle of" でバチーンと探しちゃえばいいんです。
しかし,xxx xxx burn it up xxx.
みたいなときで,熟語が,burn up の場合には前述の方法だとうまくいかないわけです。
そこで,文の末尾から,熟語の先頭の単語を探して,
んでそこ以降で最も近い場所にある熟語の最後の単語を探す。
で,その範囲で置換をする。(何言ってるかわかりませんよね。これだけだと。)
ま,続けます。
ほいで,この方法だと,最初の例の場合に失敗するわけです。


で,改善しようと思いまして,範囲をしぼったら,その間に熟語の単語が全て存在するかどうか
調べようと思ったわけです。
んでもって,これを実現するために,文の末尾から単語の出現を検索する関数を欲したわけです。
ふぅ,長かったぜ。


ただ,with-temp-buffer のオーバーヘッドってどんなもんなんでしょ?
1000個くらいの文,多くて数千の文なので,大した問題にはならん?


とりあえず,あとは本体を改善する作業が残っているけど,
なんかお腹いっぱいになっちゃった。えへ。