2015-11-21のメモです。
主に関ジン研(関東ジンギス研究会)からのリンクのためと、食べ歩きの際に前回いつ行ったかを自分で検索するために記述を残しています。稀に雑多なことを書いたりもします。
ちょっと訳あって、Ruby のブロックなし scanメソッドの機能を Emacsで使いたくなったため、それっぽい関数を Emacs Lispで実装してみた。
(defun quail-soyokaze-string-scan (regexp str &optional case-fold-p) "引数で指定した正規表現 REGEXP とマッチする部分を文字列 STR から全て\ 取り出し、リストにして返す。マッチする部分がなければ、空のリストを返す。 \nCASE-FOLD-P が non-nil の場合、マッチングの際に大文字と小文字の区別を無視\ する。CASE-FOLD-P のデフォルトは nil。" (let ( (ret (list nil)) (case-fold-search case-fold-p) ) (while (and str (string-match regexp str)) (let* ( (tmp-match-data (match-data)) (end (nth 1 tmp-match-data)) (part (list nil)) ) (while tmp-match-data (nconc part (list (match-string-no-properties (1- (length part)) str))) (setq tmp-match-data (cdr (cdr tmp-match-data)))) (setq part (cdr part) str (substring str end nil)) (nconc ret (list (or (cdr part) (car part)))) (if (zerop end) (setq str (and (string< "" str) (substring str 1 nil)))))) (cdr ret)))
Emacsだとマッチングの際に大文字と小文字の区別を無視しないのがデフォルトっぽいので、マッチングの大文字・小文字の区別を省略可能な引数で指定するようにしている。実行例はこんな感じ。
(quail-soyokaze-string-scan "..." "abcdefghijk") ;; => ("abc" "def" "ghi") (quail-soyokaze-string-scan "[A-Z]+[0-9]+" "P/abc1AC2Bd34X58 4nZY90ok7") ;; => ("AC2" "X58" "ZY90") (quail-soyokaze-string-scan "[A-Z]+[0-9]+" "P/abc1AC2Bd34X58 4nZY90ok7" t) ; case-fold-p = t ;; => ("abc1" "AC2" "Bd34" "X58" "nZY90" "ok7") (quail-soyokaze-string-scan "\\([A-Z]+\\)\\([0-9]+\\)" "P/abc1AC2Bd34X58 4nZY90ok7") ;; => (("AC" "2") ("X" "58") ("ZY" "90"))
あ、関数名のプレフィックスはこちらの都合で付けただけなので深追い無用のこと。
最近のツッコミ: