2009-10-02 135 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。