From Letters
http://programmingpraxis.com/2010/11/30/form-letters/
import re def from_letters(message, seq): def repl(m): i = int(m.group(2)) return m.group(1)+seq[i] return re.sub(r'([^\$])\$(\d+)', repl, message) S = """ Welcome back, $1! We hope that you and all the members of the $0 family are constantly reminding your neighbors there on $5 to shop with us. As usual, we will ship your order to $3 $1 $2. $0 $4 $5 $6, $7 $8 """ seq = ['Public', 'Jane', 'Q', 'Ms.', '600', 'Maple Street', 'Your Town', ' Iowa', '12345'] seq2 = ['Smith', 'John', 'Z', 'Dr.', '1234', 'Main Street', 'Anytown', 'Missouri', '63011'] print from_letters(S, seq) print from_letters(S, seq2)
scheme
"\\12345"が上手く置換できないバグがある。
(use gauche.experimental.lamb) (define S " Welcome back, $1! We hope that you and all the members of the $0 family are constantly reminding your neighbors there on $5 to shop with us. As usual, we will ship your order to $3 $1 $2. $0 $4 $5 $6, $7 $8 ") (define (from-letters s seq) (let* ((rx-generator (compose string->regexp (cut format #f "([^\\$])\\$~a" <>))) (rxs (list-tabulate (length seq) rx-generator)) (args (apply append (zip rxs (map (cut format "\\1:~a" <>) seq))))) ;;\\12345となってしまう。 (apply regexp-replace-all* s args))) (let1 seq '("Public" "Jane" "Q" "Ms." "600" "Maple Street" "Your Town" " Iowa" "12345") (from-letters S seq))
追記
先読み、後読みの正規表現を使うとよい。
先読み否定 | (?! |
先読み肯定 | (?= |
後読み否定 | (?) |
後読み肯定 | (?<= |
scheme
(use text.tree) (define (from-letters s seq) (let1 vseq (list->vector seq) (define (%replace str) (cond ((rxmatch #/^\d+/ str) => (^m (let1 i (string->number (m 0)) (list (vector-ref vseq i) (m 'after))))) (else str))) (tree->string (map %replace (string-split s #/(?<!\$)\$(?=\d+)/)))))