Convert Single Line Comments To Block Comments

匿名 (未验证) 提交于 2019-12-03 08:46:08

问题:

I need to convert single line comments (//...) to block comments (/*...*/). I have nearly accomplished this in the following code; however, I need the function to skip any single line comment is already in a block comment. Currently it matches any single line comment, even when the single line comment is in a block comment.

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

As already mentioned, "//..." can occur inside block comments and string literals. So if you create a small "parser" with the aid f a bit of regex-trickery, you could first match either of those things (string literals or block-comments), and after that, test if "//..." is present.

Here's a small demo:

$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";   } } 

Which produces the following output:

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 

Of course, there are more string literals possible in PHP, but you get my drift, I presume.

HTH.



回答2:

You could try a negative look behind: 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  ); } 

however I worry about possible strings with // in them. like: $x = "some string // with slashes"; Would get converted.

If your source file is PHP, you could use tokenizer to parse the file with better precision.

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

Edit: Forgot about the fixed length, which you can overcome by nesting the expression. The above should work now. I tested it with:

$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";; 


标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!