只查找多行 C 注释,不查找单行 C 注释
Only find multiline C comment but not single line C comments
假设我有这段文字:
cat file
/* comment */ not a comment /* another comment */
/* delete this *
/* multiline *
/* comment */
/*************
/* and this *
/************/
The End
我可以使用带有条件 ? :
的 perl
来仅删除多行注释:
perl -0777 -pE 's/(\/\*(?:\*(?!\/)|[^*])*\*\/)/(=~qr"\R") ? "" : /eg;' file
打印:
/* comment */ not a comment /* another comment */
The End
没有条件:
perl -0777 -pE 's/(\/\*(?:\*(?!\/)|[^*])*\*\/)//g;' file
not a comment
The End
有没有办法仅使用正则表达式删除多行 C 样式注释?即,不在替换中使用 perl 条件代码?
您可以使用
perl -0777 -pe 's~/\*(?:(?!\*/|/\*).)*\R(?s).*?\*/~~g' file
模式匹配
/\*
- /*
字符串
(?:(?!\*/|/\*).)*
- 除换行符以外的零个或多个字符,每个字符都不是 */
和 /*
字符序列 的起始字符
\R
- 换行序列
(?s)
- 现在,.
也将匹配换行符
.*?
- 尽可能少的任何零个或多个字符
\*/
- */
子串。
参见regex demo。
采用SKIP/FAIL方法:
perl -0777 -pe's~/\*\N*?\*/(*SKIP)^|/\*.*?\*/~~gs' file
\N
匹配所有不是换行符的内容
由于使用了 s 标志,点匹配所有字符,包括换行符。
第一个分支匹配“内联”注释,并被迫以 ^
失败(比写 (*F)
或 (*FAIL)
更短,但结果相同)。 (*SKIP)
回溯控制动词强制不重试先前的位置,因此下一次尝试在结束位置 */
之后开始。
第二个分支匹配剩余的评论,这些评论必须是多行的。
一个较短的变体,具有相同的两个分支,但这次使用 \K
从匹配结果中排除消耗的字符:
perl -0777 -pe's~/\*\N*?\*/\K|/\*.*?\*/~~gs' file
这次第一个分支成功,但是由于\K
之前的所有字符都从匹配结果中移除,所以剩余的空字符串被替换为空字符串。
这两个 search/replace 与更便携的没有太大区别:
s~(/\*.*?\*/)|/\*[\s\S]*?\*/~~g
但工作量较小(不需要捕获组,替换字符串为空)。
假设我有这段文字:
cat file
/* comment */ not a comment /* another comment */
/* delete this *
/* multiline *
/* comment */
/*************
/* and this *
/************/
The End
我可以使用带有条件 ? :
的 perl
来仅删除多行注释:
perl -0777 -pE 's/(\/\*(?:\*(?!\/)|[^*])*\*\/)/(=~qr"\R") ? "" : /eg;' file
打印:
/* comment */ not a comment /* another comment */
The End
没有条件:
perl -0777 -pE 's/(\/\*(?:\*(?!\/)|[^*])*\*\/)//g;' file
not a comment
The End
有没有办法仅使用正则表达式删除多行 C 样式注释?即,不在替换中使用 perl 条件代码?
您可以使用
perl -0777 -pe 's~/\*(?:(?!\*/|/\*).)*\R(?s).*?\*/~~g' file
模式匹配
/\*
-/*
字符串(?:(?!\*/|/\*).)*
- 除换行符以外的零个或多个字符,每个字符都不是*/
和/*
字符序列 的起始字符
\R
- 换行序列(?s)
- 现在,.
也将匹配换行符.*?
- 尽可能少的任何零个或多个字符\*/
-*/
子串。
参见regex demo。
采用SKIP/FAIL方法:
perl -0777 -pe's~/\*\N*?\*/(*SKIP)^|/\*.*?\*/~~gs' file
\N
匹配所有不是换行符的内容
由于使用了 s 标志,点匹配所有字符,包括换行符。
第一个分支匹配“内联”注释,并被迫以 ^
失败(比写 (*F)
或 (*FAIL)
更短,但结果相同)。 (*SKIP)
回溯控制动词强制不重试先前的位置,因此下一次尝试在结束位置 */
之后开始。
第二个分支匹配剩余的评论,这些评论必须是多行的。
一个较短的变体,具有相同的两个分支,但这次使用 \K
从匹配结果中排除消耗的字符:
perl -0777 -pe's~/\*\N*?\*/\K|/\*.*?\*/~~gs' file
这次第一个分支成功,但是由于\K
之前的所有字符都从匹配结果中移除,所以剩余的空字符串被替换为空字符串。
这两个 search/replace 与更便携的没有太大区别:
s~(/\*.*?\*/)|/\*[\s\S]*?\*/~~g
但工作量较小(不需要捕获组,替换字符串为空)。