2009-10-02 14 views
6

私は単線コメント(//...)をブロック(/*...*/)にブロックする必要があります。私はこれを次のコードでほぼ達成しました。しかし、私は、ブロックコメントに既にある行コメントをスキップする機能が必要です。現在、1行のコメントがブロックコメントに含まれている場合でも、1行のコメントに一致します。単線​​コメントをブロックするコメント

## Convert Single Line Comment to Block Comments 
function singleLineComments(&$output) { 
    $output = preg_replace_callback('#//(.*)#m', 
    create_function(
    '$match', 
    'return "/* " . trim(mb_substr($match[1], 0)) . " */";' 
    ), $output 
); 
} 

答えて

1

あなたが背後にある負の外観を試みることができる:

## Convert Single Line Comment to Block Comments 
function sinlgeLineComments(&$output) { 
    $output = preg_replace_callback('#^((?:(?!/\*).)*?)//(.*)#m', 
    create_function(
    '$match', 
    'return "/* " . trim(mb_substr($match[1], 0)) . " */";' 
), $output 
); 
} 

http://www.regular-expressions.info/lookaround.htmlは、しかし、私は彼らで//で可能な文字列を心配します。 like: $ x = "スラッシュ付きの文字列//"; 変換されますか。

ソースファイルがPHPの場合は、tokenizerを使用してより正確にファイルを解析できます。

http://php.net/manual/en/tokenizer.examples.php

編集: あなたが式をネストすることによって克服することができ、固定長、忘れてしまいました。上記は今すぐうまくいくはずです。

$foo = "// this is foo"; 
sinlgeLineComments($foo); 
echo $foo . "\n"; 

$foo2 = "/* something // this is foo2 */"; 
sinlgeLineComments($foo2); 
echo $foo2 . "\n"; 

$foo3 = "the quick brown fox"; 
sinlgeLineComments($foo3); 
echo $foo3. "\n";; 
+0

私は$ x = "スラッシュ付きの文字列//"と心配していません。 $ x = "some strings/* with slashes * /";となります。それは実際に好まれるでしょう。一方、私はあなたが示唆した変更を追加し、コンパイルエラーを得ました。 警告:preg_replace_callback()[function.preg-replace-callback]:コンパイルに失敗しました:lookbehindアサーションは、C:\ Wamp \ www \ LessCSS \ Site \ cleaner \ inc \ util.php 29 – roydukkey

+1

PHPのルック・バック機能は、固定長アサーションのみをサポートしています。つまり、定義されていない数の文字にマッチするルックバックビハインド正規表現を書くことはできません。これは*と?の使用を排除します。詳細はこちら:http://www.php.net/manual/en/regexp.reference.assertions.php –

+0

ヘッドアップに感謝します。今すぐ動作するはずです。 –

3

すでに述べたように、「//...」ブロックコメントと文字列リテラル内で発生する可能性があります。私はそれをテストしました。したがって、助けを借りて小さな正規表現を作成すると、最初にそれらのもの(文字列リテラルまたはブロックコメント)のいずれかと一致し、その後に "//..."が存在するかどうかをテストできます。次の出力を生成

$code ='A 
B 
// okay! 
/* 
C 
D 
// ignore me E F G 
H 
*/ 
I 
// yes! 
K 
L = "foo // bar // string"; 
done // one more!'; 

$regex = '@ 
    ("(?:\\.|[^\r\n\\"])*+") # group 1: matches double quoted string literals 
    | 
    (/\*[\s\S]*?\*/)   # group 2: matches multi-line comment blocks 
    | 
    (//[^\r\n]*+)    # group 3: matches single line comments 
@x'; 

preg_match_all($regex, $code, $matches, PREG_SET_ORDER | PREG_OFFSET_CAPTURE); 

foreach($matches as $m) { 
    if(isset($m[3])) { 
    echo "replace the string '{$m[3][0]}' starting at offset: {$m[3][1]}\n"; 
    } 
} 

はここで小さなデモです。もちろん、

replace the string '// okay!' starting at offset: 6 
replace the string '// yes!' starting at offset: 56 
replace the string '// one more!' starting at offset: 102 

、私は推測し、そこにPHPで可能なより多くの文字列リテラルがありますが、あなたは私のドリフトを取得します。

HTH。

関連する問題