Bruce.です。
davi さんは書きました (2009/02/27 19:24):
> しかし、いくら「順番を気に」していても、思わぬところで
> 二重置換されてしまったりして、意図通りの結果が出ない
> 場合があります。
>
> 例えば、簡体字だと「穀」は全部「谷」に統一してしまい
> ますね。すると、それを繁体字に戻そうとして
>
> s/谷/穀/g
>
> とだけしてしまうと、「硅谷」のような「谷間」の
> 字義についてまで、「硅穀」と置換されてしまって
> 困ります。
>
> 穀物の意味であり、なおかつ「谷」になってしまって
> いる単語を列挙した辞書を作って、
>
> s/谷([倉物類])/穀$1/g
>
> みたいにしないとダメですね。
> しかし、[倉物類]の部分の「倉」が、それ以前の置換定義で
> 既に例えば「藏」などの字に置換されていた場合は、
>
> s/谷([倉物類])/穀$1/g
>
> の定義は無意味になります。
>
> すると、バッドノウハウで
>
> s/倉/藏/g
> (例えば100行分の定義を中略)
> s/谷([藏物類])/穀$1/g
>
> みたいにしないとダメ。
条件が厳しい方から先にやってけば良いって話じゃないんですか?
上記の例で言うと、倉→藏も条件を厳しくしないとダメですけど。
事情が良くわかりませんが、そこまである文字が出てくる「文脈」に
依存するのなら話は簡単じゃないと思いますが。
>
> こういうの、一時的にフックして置いて、置換させないという
> ような方法は何か無いのかなぁ…と、もう何年も探しています。
>
> そこで思い出すのがsedの
>
> y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/
>
> なんていう便利な命令です。
>
> こういうのは、中身的にはどんな風になっているんでしょうね?
>
> 例えばawkでこれをやろうとすると、gsubをウンザリするほど列挙
> することになるわけですけど、結局、sedもエレガントに見える
> 書き方をしているだけで、中身ではホールドスペースを使って
> 複雑なことをやっているんでしょうか?
ASCIIの範囲に限れば、思い切り単純です。
たとえば
ABCDE → vwxyz
という置換を行う場合
work['A'] ← 'v'
work['B'] ← 'w'
work['C'] ← 'x'
work['D'] ← 'y'
work['E'] ← 'z'
としてそのほかは
work['F'] ← 'F'
work['G'] ← 'G
…
work['a'] ← 'a'
work['b'] ← 'b'
・・・
work['x'] ← 'x'
work['y'] ← 'y'
work['z'] ← 'z'
というテーブルを組み立てて、置換の対象となる文字列を頭からなめていって
newstr[i] = work[oldstr[i]]
を順に文字列の終端までやるだけです。
文字集合が大きいものになるとこの手が使えない、使いにくいのは自明ですね。
--
木村浩一
I thought what I'd do was, I'd pretend I was one of those deaf-mutes or should I?
mail kbk [at] kt.rim.or.jp
web www.kt.rim.or.jp/~kbk/zakkicho/
homepage3.nifty.com/farstar/