2009-10-02 136 views
6

我需要將單行註釋(//...)轉換爲註釋(/*...*/)。我在下面的代碼中幾乎完成了這個任務;然而,我需要這個函數來跳過任何一行註釋已經在塊註釋中。目前它與任何單行註釋匹配,即使單行註釋在塊註釋中也是如此。將單行註釋轉換爲註釋

## 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

你可以嘗試一下負背後:http://www.regular-expressions.info/lookaround.html

## 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 
); 
} 

但是我擔心在他們//可能的字符串。如: $ 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 =「一些字符串/ *斜槓* /」;.這實際上是首選。另一方面,我添加了您所建議的更改並收到編譯錯誤。 警告:preg_replace_callback()[function.preg-replace-callback]:編譯失敗:lookbehind斷言在C:\ wamp \ www \ LessCSS \ Site \ cleaner \ inc \ util.php中的偏移量6處不是固定長度29 – roydukkey 2009-10-02 04:22:54

+1

PHP的外觀只支持固定長度的斷言。這意味着你不能編寫一個匹配未定義字符數的後備式正則表達式,這將排除使用*和?。更多信息在這裏:http://www.php.net/manual/en/regexp.reference.assertions.php – 2009-10-02 04:39:12

+0

謝謝你的擡頭。應該現在工作。 – 2009-10-02 16:25:15

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。