我有一个 Java 项目,其中有 JavaDoc 注释
/** ... */
其他多行注释
/* ... */
行评论
// ...
以及我自己的“解释性评论”
//* ...
当我发布代码时,我希望删除所有行注释 - 但不是其他注释。我想我会用 sed 来做到这一点,但到目前为止我还没有成功。我正在尝试以下操作:
#!/bin/bash
while read -d $'\0' findfile ; do
echo "${findfile}"
mv "${findfile}" "${findfile}".veryold
cat "${findfile}".veryold | sed -e 's|//[^\*"]*[^"]*||' -e 's/[ ^I]*$//' | grep -A1 . | grep -v '^--$' > "${findfile}"
rm -f "${findfile}".veryold
done < <(find "${1}" -type f -print0)
我做错了什么?请注意,不应删除“...”中的 //,因为它们可能是 URL 的一部分。
关键部分是
-e 's|//[^\*"]*[^"]*||'
答案1
首先,您的脚本可以简化为一行:
find "$1" -type f -name '*.java' -print -exec sed -i -e '...' '{}' \;
其次,这是一个使用正则表达式很难解决的问题,因为它们的语法不支持上下文敏感。这意味着您无法知道 a 是否//
在字符串文字内。
忽略这一事实,您可以尝试:
s|//[^*"][^"]*$||
这假设您不使用双引号作为评论的一部分。
答案2
我不确定 sed 是否可以对其他多行进行复杂的匹配。
使用 perl 删除所有注释:
perl -e '$_=join("",<>);s%/\*.*?\*/%%gs;s%//.*$%%gm;print' SomeFile.java
使用 perl 删除“”对之外的所有非 javadoc 注释:
perl -e '$_=join("",<>);s%/\*([^*].*?)?\*/%%gs;s%^([^\"\n\r]*(\"[^\"\n\r]*\"[^\"\n\r]*?)*?)//([^*\n\r].*)?$%$1%gm;print' SomeFile.java
这是一个更紧凑的版本,搜索所有 *.java 文件并生成 .bak 文件:
find . -name '*.java' -print0 | xargs -r -0 perl -n -p -0 -i.bak -e 's%/\*([^*].*?)?\*/%%gs;s%^([^\"\n\r]*(\"[^\"\n\r]*\"[^\"\n\r]*?)*?)//([^*\n\r].*)?$%$1%gm'
但这会删除 /** */ 内的 //
需要一个更复杂的脚本来避免这种情况:
您必须将 /** */ 替换为 __temp_comment_# (将 # 替换为不断变化的数字)
然后用 __temp_quote_ 替换“...”#
然后删除评论
然后将 __temp_quote_# 和 __temp_comment_# 改回原始文本