使用 sed 将 C 风格注释转换为 C++ 风格

使用 sed 将 C 风格注释转换为 C++ 风格

我正在尝试将单行“C”样式注释转换为“C++”样式。下面的“sed”还不错,但是如果任何前导代码(注释之前的代码)中有任何“/”,它当然会失败:

sed -i 's,\(^[^\/]*\)\/\*\([^\*]*\)\*\/[ ]*$,\1\/\/\2,' filename

我希望我能做的是这样的:

... [^\\/\\*] ...

即否定“/*”,这当然不起作用,但是经过几个小时的搜索,我找不到简单的解释如何正确地做到这一点:(这似乎不应该是火箭科学。

例如,这些字符串:

blah blah        /* comment */
blah blah / blah /* comment */
blah blah        /* comment */ blah
blah blah / blah /* comment */ blah 

...应该这样转换:

blah blah        // comment 
blah blah / blah // comment 
blah blah        /* comment */ blah  (this CAN'T be converted)
blah blah / blah /* comment */ blah  (this CAN'T be converted)

...显然,如果“C”注释后面有代码,则不会发生转换。

我将在文件之前和之后进行仔细的视觉比较,因此不需要在文字中处理“/*”,也不想转换任何多行内容。

请注意,我认为这是一个“否定”问题,但也许还有另一种方法。我只需要捕获“/*”之前的所有内容,我不在乎如何捕获。

跟进下面的答案

好吧该死!我发现我完全误解了一些基本的东西:

.*/\*

...读取:“除了斜杠星号后跟斜杠星号之外的任何内容”,所以实际上我免费得到了我的“否定”:-)

所以,比 Barmar 更进一步:

sed -i 's,^\(.*\)/\*\(.*\)\*/\s*$,\1//\2,' filename

...甚至会捕捉到这个:

blah / * blah        /* co / mme * nt */

并输出:

blah / * blah       // co / mme * nt 

启示。

答案1

尝试这个:

sed 's,^\(.*\)/\*\([^/]*\)\*/$,\1//\2,'

这不会转换包含嵌入/字符的注释。或者,您可以使用:

sed 's,^\(.*\)/\*\(.*\)\*/$,\1//\2,'

如果同一行有两个注释,这会做错误的事情,例如

blah blah        /* comment1 */ blah /* comment2 */

将转换为

blah blah       // comment1 */ blah /* comment2

使用 PCRE 版本可能会做得更好sed,因为您可以使用负前瞻来测试嵌入的注释。

另请注意,,在命令中用作分隔符s意味着您不必转义/正则表达式中的所有字符——这就是/当正则表达式包含大量/.

答案2

也许最安全的方法是首先测试您不想影响的行,b如果有匹配则退出脚本。

sed '\|\*/.*/\*|b'

*里面有所有的星星,这有点难以阅读,但基本上 if/*发生后将*/ sed退出执行其脚本,自动打印该行,并拉入下一行以开始下一行循环。对于匹配的行,不会执行其后的任何命令。

另一种方法是使用test,如果在成功替换后b未提供任何牧场标签,则同样会从脚本中牧场牧场:bs///

sed 's|/\*|&|2;t'

它尝试用自身替换该行中第二次出现的模式,如果成功,它会以相同的方式进行分支b

所以...

sed 's|/\*|&|2;s|\*/|&|2;t
     s|/\*\(.*\)\*/ *$|//\1|'

...将以第一次且唯一一次出现的以及任意数量的尾随空格字符/*结尾//的行替换第一次且唯一一次出现的 。*/这是有效的,因为t适用于在其之前发生的任何替换,因此如果其中一个或另一个t成功,sed则会分支。

不过,我可能在这里犯了错误,因为我对 C 或 C++ 不太熟悉,并且不确定在这种/\*.*\*/.*\*/情况下会发生什么 - 上面的脚本b远离了 .也许您应该只测试 2*/或仅测试 2 /*。但至少希望我能够将这一概念传达给更了解的人。

答案3

我碰巧需要上述内容 - 但也需要多行 - 所以我将 Barmar 的答案与我自己的一些 sed 合并来实现此目的

sed -e '/\/\*/,/\*\//{s/^\( *\)\/\*/\1~~/g;s/^\( *\) \*\//\1~~/g;s/^\( *\) \*/\1~~/g;s/~~/\/\//g};s/\*\*/\/\//g;s,^\(.*\)/\*\(.*\)\*/\s*$,\1//\2,'

(顺便说一句,如果在 Mac 上,您需要 gsed,否则您会收到上面的错误)

这是之前/之后的差异

***************
*** 1,13 ****

! /*
     FOO
!  */

! /*
!  * BAR
!  */

! blah blah        /* comment */
! blah blah / blah /* comment */
  blah blah        /* comment */ blah
  blah blah / blah /* comment */ blah
--- 1,13 ----

! //
     FOO
! //

! //
! // BAR
! //

! blah blah        // comment
! blah blah / blah // comment
  blah blah        /* comment */ blah
  blah blah / blah /* comment */ blah

相关内容