JavaScript Diary

正規表現で悩む(誰か教えて) [ 2001/12/08 ]

WEBで提供するなら尚更、スクリプトファイルなどのファイルサイズは小さいに越したことはないのですが、サイズを小さくしようと思った場合、手っ取り早いのは「余計な空白文字を詰める」ことだと思います。
例えば peace-js-lib-JSME.txt なんかは、およそ 3/4 程度に圧縮されています。
どうやってここまでしているのかというと今までテキストエディタである程度マクロを作ってバリバリ置換していたわけです。

さて、この作業をもうちょっと手軽に JavaScript で出来ないかということで挑戦してみましたが、いきなり詰まりました。

// Googleを開く関数
function openGoogleWindow(){
    var win = window.open( 'http://www.google.com/', '_blank' );
}

↑を一つのプログラムと考え、これ全体を text という変数に代入したと考えて下さい。
圧縮する前に先ず、コメント部分を削除します。
つまり、// 以下を削除しますが、正規表現を使うと以下のようになります(不備があります)。

text = text.replace( /\/\/.*/g, "" );

さて、text に何が代入されたかというと以下です。


function openGoogleWindow(){
    var win = window.open( 'http:
}

・・・まあ、考えてみれば当たり前です。

パッと思いつく、これの対処法は 「 // 以下の文字列にはマッチさせるが、http: で始まるものは除く」です。
正規表現はサッパリなんですが調べてみたらありました。「否定」が。
例えば [^01] では 0又は1以外の文字にマッチします。
また、(あいうえお|かきくけこ) は「あいうえお」または「かきくけこ」にマッチします。

これらが分かったとき、正規表現しらない人間が必ずするであろう間違いが以下です。

text = text.replace( /[^(http\:)]\/\/.*/g, "" );

これの意図を皆さんが理解してくれることを祈りますが、僕はこれを [ http:という文字列で始まらない//以降の文字列 ] と解釈したわけです。えぇえぇ、僕は初心者です、馬鹿にせんといて下さい。

うぶぶ、実際は h 又は t 又は p 又は : 以外で始まる//以降の文字列 として解釈されます。
例えば、これでは以下のようなコメントは削除されません。

var value = t// value に t を代入

そんなこんなで正規表現には「1文字の否定」はあるものの「文字列の否定」はないのかっちゅう話です。

あと、タグのみを削除するときは最小マッチを意識して、

text = text.replace( /<[^>]*>/g, "" );

としますが、これは正しいんです。では、これの応用で /* 〜 */ 形式の一行コメントを削除することを考えます。

text = text.replace( /\/\*[^(\*\/)]*\*\//g, "" );

勿論、これも駄目です。↓のような * や / を含むようなコメントは削除されなくなります。

/* *comment* */

もうサッパリですわ。誰か教えて下さい。まじで。

妥協しながら、試行錯誤しながらとりあえず完成したもの