作者: Bruce.
日時: 2009/3/03(01:25)
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/