dポイントプレゼントキャンペーン実施中!

コメントアウト以外を置換対象とする正規表現について質問です。

以下の(1)の入力に対して(2)の結果を得たいのですが、
綺麗な正規表現を使って置換する方法を教えて下さい。

とりあえず複数回に分けて無理やり置換したのですが、
とても汚いコードになってしまいました。。。

(前提)
・コメントは/*...*/ と //... の2種類
・コードは改行を含めて1変数に格納されている
・目的はコメントアウト以外の「abcde」を「aaaaa」に置換すること


(1)
----------------------------------------------------
/* abcde fghij */ abcde fghij /* abcde fghij */
abcde fghij // abcde fghij abcde fghij
/*
abcde
fghij
*/
abcde fghij /* abcde fghij */
----------------------------------------------------


(2)
----------------------------------------------------
/* abcde fghij */ aaaaa fghij /* abcde fghij */
aaaaa fghij // abcde fghij abcde fghij
/*
abcde
fghij
*/
aaaaa fghij /* abcde fghij */
----------------------------------------------------


(考えた方法)
----------------------------------------------------
$st = "#START#";
$ed = "#END#";
s/\b(abcde)\b/${st}$1${ed}/sg;
s/(\/\*.*?)${st}(.*?)${ed}(.*?\*\/)/$1$2$3/sg;
while(s/(\/\/.*?)${st}(.*?)${ed}/$1$2/g){};
s/${st}abcde${ed}/aaaaa/sg;
----------------------------------------------------

ご回答よろしくお願いします。

A 回答 (3件)

全ての条件をクリアしているかはわかりませんが。



s{(//.*?\n|/\*.*?\*/|abcde)}{$1 eq 'abcde' ? 'aaaaa' : $1}egs;
    • good
    • 0
この回答へのお礼

回答ありがとうございます!とてもシンプルな置換ですね!

コメント文と対象文字列をor取りして、後でコメント文のマッチを回避する方法、
とても勉強になりました。検索・置換回数もNo.2のご回答より少なくて済みそうです。

お礼日時:2010/11/02 21:28

とりあえず質問の例は置き換えることができます。

なお、面倒なので非格納型の丸括弧は使っていません。

use strict;
my $str = join '', <DATA>;
$str =~ s/((\/\*.*?\*\/|\/\/.*?\n|[ \n]*)*)((abcde)?)/$1@{[$3 ? 'aaaaa' : '']}/sg;
print $str;

__DATA__
/* abcde fghij */ abcde fghij /* abcde fghij */
abcde fghij // abcde fghij abcde fghij
/*
abcde
fghij
*/
abcde fghij /* abcde fghij */
    • good
    • 0
この回答へのお礼

素早い回答ありがとうございます!

目からウロコが大量に流れ出ました。このような方法で
コメントアウト中の対象文字列マッチを回避することが出来るのですね!

本質ではありませんが、eオプションを使わずに
3項間演算子を計算させるための配列@{[...]}の使い方に感動しました。

お礼日時:2010/11/02 21:16

ちょっと考えなきゃならないことがあって, 例えば


/*
* abcde // */
abcde
*/
とあったときにどうなっているとうれしいんでしょうか?

この回答への補足

ご回答ありがとうございます。

これは・・・
複数行コメント内にある//は、
コメントアウトとして機能しない。
として処理してほしいです。

逆に以下のような場合は(文法誤りですが)、
1行コメント優先で処理をしてほしいです。
// /*
abcde
*/

ただ、前提として
・プログラムが文法的に正しいこと
を追加させて下さい。

つまりご提示されたケースは対象外とさせて下さい。
#強制実行したら2番目のabcdeが置換対象になると思います。

補足日時:2010/11/02 07:57
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!