星田さんの記事に付いてのコメント。
データの整形ならSchemeで出来そうな・・まあ、デキるところまでやってみるか。魔法使いの家の時はどうしても分からなかったらこちらを参考に出来たんだけど、今回Gauche特有のライブラリとかを使ってるっぽいんだよなぁ
と言うわけで、コッチにRacket特有のライブラリ + SRFIを使ったヴァージョンを上げておきます。
今回使ったANSI Common Lisp関数とRacket関数の対応表はここに。
注: ANSI Common Lispには標準では正規表現に関する機能は搭載してないが、代替の手法が山ほど提供されている、と言うのがこのプログラムでは分かる。
一方、以前にも書いたが、Schemeも標準ではもちろん正規表現を取り扱っていないが、長らくUNIX系OSと仲良くしてたので、実装としては正規表現を扱う拡張をしてる例が多く、Racketもその例に漏れない。
提示コードの
(regexp-replace #px"[^[:alnum:]]+" (format "~a" exp) "_")
と言うのは与えられた文字列((format "~a" exp))で、アルファベットや数字「じゃない」文字を見かけたら"_"で置き換えろ、と言う事を意図していて、ANSI Common Lispでのオリジナルバージョンのsubstitute-if、complement、alphanumericpの3つの関数を使ったものを正規表現の置換関数regexp-replaceだけで置き換えている。
そしてRacketで「アルファベットまたは数値」と言うのはまとめて[:alnum:]として指定する。そして^は「NOT」を意味する。
つまり、原作の
(complement #'alphanumericp)
が
^[:alnum:]
としてRacketの正規表現では表される。
そして、
[^[:alnum:]]
は「アルファベットと数値以外のあらゆる文字にマッチする」と言う意味になる。
なお、+は「それが1文字以上繰り返した場合」と言う意味。
このように、正規表現は短い表現で複雑な意味を盛り込む事が可能だが、そのため読解しづらく書きづらく、慣れるまで時間がかかる。
なお、一般的な正規表現に対する本としてはこういう本があったりする。