現実の複雑な文字列処理を望むならば、exprの演算子:(と演算子|)を駆使しなければならない。人生同様、いくつかの局面で、あなたと私はexprに裏切られる。やれやれ。
sedやawkといったユーティリティたちを使いこなせるならば、うんうん、それもまたユニックスだね。人生同様、ユーティリティたちは銀の弾丸であなたと私の足を撃ちぬく。やれやれ。
expr "X$s" : 'X\([0-9a-z]*\)'
| 入力 | 出力 | 結果コード | |
|---|---|---|---|
| BSD | GNU | ||
| 空文字列 | 空文字列 | 1 |
1 |
foo |
foo |
0 |
0 |
BAR |
空文字列 | 1 |
1 |
0 |
0 |
0 |
1 |
0000 |
0000 |
0 |
1 |
0x00 |
0x00 |
0 |
0 |
いうまでもなく結果コードは演算子|の評価を左右する。
expr 'a' : '\(b\)'が0と空文字列のどちらを出力するのかについて、POSIX標準はあいまいである。QNX 4.25のexprは0を返す。
Tru64の
exprはマッチ結果を数値として扱う。$ expr 00001 : '.*\(...\)' 1
世に非互換の種は尽きまじとAutoconfは教えている。
Tru64は腹を切って死ぬべきだ。理由はexprによる部分文字列抽出を不能ならしめた犯人であり、exprを殺すなら自分が死ぬべきが当然だからだ。
expr "X$s" : '\(X[0-9a-z]*\)' | sed 's/^.//'
マッチが成功するとき、マッチ結果が空でなく数値に変換されない文字列になるように、適当な文字(たとえばX)で接頭する。マッチが失敗するとき、あいまいなexprは空文字列または0を出力する。パイプは結果コードを無視し、sedは最初の一文字を削る。
すべての現実の複雑な文字列処理を生まれる前に消しされるほど、この回避策は銀の弾丸ではない。この回避策には優れた点がふたつある。まず、セックス・シーンがないこと、それから一人もひとが死なないことだ。
Cコンパイラは遍在する。ならばCで書けばよい。あるいはLuaをビルドしよう。逆説的に、だから、Luaがビルドされるまでのほんのわずかなあいだの、これは神話なのだ。