手を抜いたけどとりあず版。

どもども。
かまたまにはまっていて,乾麺で最初に試して,もひとつだったので,
冷凍麺にいったらかなりうまくなって大喜びもつかの間,上唇を噛んでしまい,
口内炎からのシミて痛い,いらいらする,笑うと痛い,乾燥しているから治りにくい
のコンボを味わって,もう2度とうどんなんて喰わないなんて言わないよ絶〜対〜。
whitypig です。ふぅ。
かまたま未経験で東京に住んでいる人は,新宿の東京麺通団にいっときましょう。
吉祥寺にもありますが,新宿の方がいいです。新宿店には酢が置いてあり,
この酢がめちゃうまい。吉祥寺にはござんせん。
香川行って本場のうどんを食ってみたいなぁ。
というか,あの酢について情報をお持ちのかた教えてください。
普通の酢じゃないよなぁ。加工してあるのかなぁ?


あー,さて,とりあえずですが,こないだできた string-match-backward を使って
改良してみました。ほいで,テストも通ったのでま,今のところは
大丈夫そう。けど,手を抜いたのでぼろが出る可能性大だな・・・。
というか,el-expectations.el バンザイ。これのおかげで,
安心して関数を入れ替えられるよ!
ありがとう 作者の rubikitch さん!

(defun tango-string-match-backward (regexp string &optional start)
  "Return index of start of first match for REGEXP in STRING, or nil"
  (with-temp-buffer
    (insert string)
    (goto-char (or start (point-max)))
    (if (re-search-backward regexp nil t)
        (match-beginning 0)
      nil)))

(defun tango-replace-paren-with-answer-3 (sentence answers)
  (let ((case-fold-search nil)
        first-word (first-word-beg 0) (first-word-end 0)
        last-word (last-word-beg 0) (last-word-end 0)
        (rexp "\\(\\W\\|[()]\\)")
        (start (1- (length sentence)))
        (need-to-loop nil))
    (setq first-word (concat rexp (first answers) rexp))
    (setq last-word (concat rexp (car (last answers)) rexp))
    (setq need-to-loop t)
    (while (and need-to-loop (tango-string-match-backward rexp sentence start))
      (setq first-word-beg (- (match-beginning 0) (+ 2 (length (first answers)))))
      (setq first-word-end (1- (match-end 0)))
      (setq start first-word-beg)
      (setq need-to-loop nil)
      (dolist (elem answers)
        ;; 答えの単語のうち1つでも見つからなかったら,探し直す必要あり。
        (unless (string-match elem sentence first-word-beg)
          (setq need-to-loop t))))
    ;; 熟語が文頭にある場合は見つけられてないので,その場合かどうかを調べる。
    (when need-to-loop
      (unless (string-match (concat "^" (first answers) "\\(\\W\\|[()]\\)") sentence)
        (error (format "Cannot find %s in tango-replace-paren-with-answer-3!" first-word)))
      ;; マッチした場合は,先頭なので,0。
      (setq first-word-beg 0))
    (dolist (elem answers)
      (setq pat (concat rexp "\\(" elem "\\)" rexp))
      (if (string-match pat sentence first-word-beg)
          (setq sentence (replace-match "()" nil nil sentence 2))
        ;; A profusion of ... の様な場合に対応。
        (progn
          (string-match (concat "\\(^" elem "\\)" rexp) sentence first-word-beg)
          (setq sentence (replace-match "()" nil nil sentence 1)))))
    sentence))

;; 他にもテストはいっぱいあるけど,これだけ抜粋。
;; グリーンがでるとうれしいね。うふふ。
(expectations
  (expect "Spanning more than three centuries, this movement grew from () () () a few hundred English colonists to a floodtide of newcomers numbering in the millions."
    (tango-replace-paren-with-answer-3 "Spanning more than three centuries, this movement grew from a trickle of a few hundred English colonists to a floodtide of newcomers numbering in the millions." '("a" "trickle" "of"))))