kobapan@wiLiki
Login
Gauche

Gauche:文字列の操作

見出し

目次

文字列の置換: string-replace[srfi-13]、regexp-replace、regexp-replace-all

string中でregexpにマッチした部分をsubstitutionで 置き換えます。regexp-replaceは最初にマッチした部分のみを置き換え、 regexp-replace-allは全てのマッチを置き換えます。 substitutionは文字列か手続きです。 文字列の場合、バックスラッシュに続く数値、もしくは \k<name>という形式でサブマッチ文字列を参照できます \0はマッチ文字列全体を参照します。文字列リテラルにバックスラッシュを 埋め込む場合は二つのバックスラッシュが必要であることに注意して下さい。 バックスラッシュそのものをsubstitution中で使いたい場合は 二つのバックスラッシュを重ねます; 文字列リテラルの場合は4つのバックスラッシュが 必要になります。

(regexp-replace #/def|DEF/ "abcdefghi" "...")
  ⇒ "abc...ghi"
(regexp-replace #/def|DEF/ "abcdefghi" "|\\0|")
  ⇒ "abc|def|ghi"
(regexp-replace #/def|DEF/ "abcdefghi" "|\\\\0|")
  ⇒ "abc|\\0|ghi"
(regexp-replace #/c(.*)g/ "abcdefghi" "|\\1|")
  ⇒ "ab|def|hi"
(regexp-replace #/c(?<match>.*)g/ "abcdefghi" "|\\k<match>|")
  ⇒ "ab|def|hi"
(regexp-replace-all #/\n/ "aaa\nbbb\n" "<br/>")
  ⇒ "aaa<br/>bbb<br/>"

substitutionが手続きである場合、string中の各マッチについて、 マッチオブジェクトを引数としてその手続きが呼ばれます。その手続きが返す 値をdisplayで表現したものが置換文字列として使われます。

(regexp-replace #/c(.*)g/ "abcdefghi"
                (lambda (m)
                  (list->string
                   (reverse
                    (string->list (rxmatch-substring m 1))))))
 ⇒ "abfedhi"

註: regexp-replace-all は文字列でマッチした部分の後ろの部分に ついて再帰的に自分自身を適用します。従って、regexpが 文字列先頭のアサーション (^) を含んでいても、それはstringの 先頭だけにマッチするとは限りません。

註: 文字列中の、正規表現にマッチする部分すべてに対して何か操作をしたいが、 置き換えた文字列が欲しいわけではない、という場合は、 gauche.lazyモジュールのlrxmatchや、 gauche.generatorモジュールのgrxmatchが使えるでしょう。 これらは文字列に対して繰り返し正規表現でのマッチを、必要に応じて適用し、 前者はマッチオブジェクトの遅延シーケンスを、後者はマッチオブジェクトを生成する ジェネレータを返します。

(map rxmatch-substring (lrxmatch #/\w+/ "a quick brown fox!?"))
  ⇒ ("a" "quick" "brown" "fox")}}}

参考

Gauche ユーザリファレンス: 正規表現 Gaucheでの文字列の作り方のメモ

正規表現で文字列を取得

(rxmatch-let (rxmatch #/(\d+):(\d+):(\d+)/
                      "Jan  1 23:59:58, 2001")
   (time hh mm ss)
  (list time hh mm ss))
;; ⇒ ("23:59:58" "23" "59" "58")

(rxmatch-let (rxmatch #/(\d+):(\d+):(\d+)/
                      "Jan  1 23:59:58, 2001")
   (#f hh mm)
  (list hh mm))
;; ⇒ ("23" "59")
(rxmatch-let (rxmatch #/(\d+):(\d+):(\d+)/
                      "Jan  1 23:59:58, 2001")
   (#f hh))
;; ⇒ "23"

参考

Gauche ユーザリファレンス: 正規表現

フォーマット、文字列の補間

(let ((str "abc")
            (num 20))
        (format #f "~a = ~s   ~s = ~d = ~b = ~o = ~x"
          str str num num num num num))
;;"abc = \"abc\"   20 = 20 = 10100 = 24 = 14"

a … ascii出力。displayによる出力。 s … S式出力。writeによる出力。 d … 10進数。 b … 2進数。 o … 8進数。 x … 16進数。xを指定するかXを指定するかで違いがあって、xなら「abcdef」を使い、Xなら「ABCDEF」を使う。

フォーマットの細かな指定が必要ないなら、文字列の補間を使うこともできる。 文字列を「"……"」と書く代わりに「#"……"」と書いて、補間をしたい位置に「~式」または「~|変数名|」と書く。

#"This is Gauche, version ~(gauche-version)."
;; ⇒ "This is Gauche, version 0.9.5."

#"Date: ~(sys-strftime \"%Y/%m/%d\" (sys-localtime (sys-time)))"
;; ⇒ "Date: 2002/02/18"

(let ((a "AAA")
      (b "BBB"))
 #"xxx ~a ~b zzz")
;; ⇒ "xxx AAA BBB zzz"

#"123~~456~~789"
;; ⇒ "123~456~789"

(let ((n 7)) #"R~|n|RS")
;; ⇒ "R7RS"

(let ((x "bar")) #"foo~|x|.")
;; ⇒ "foobar"

参考

フォーマット出力 文字列の補間

Gauche Scheme Lisp

Debian
Emacs
Firefox
Gauche
JavaScript
Linux
Scheme
org-mode/latex

More ...