注释提取器

Comment extractor

本文关键字:提取 注释      更新时间:2023-10-16

我正在寻找命令行工具或用于C,C++,Python或Node的库.js它可以从多种语言的源文件中提取注释。

例如,给定"bob.c":

int main(){ //Here is a comment
  int i=3;  /*Another comment*/
}

应返回以下内容:

Here is a comment
Another comment

可能包含行号。

这应该适用于"bob.py","bob.js","bob.css","bob.rb","bob.asm"等。

这个问题与另一个问题不同,因为我不仅对 C 风格的评论感兴趣,而且对其他评论也感兴趣。

此外,我对正则表达式作为解决方案深表怀疑。评论式短语可以以非常复杂的方式位于引用的文本中;我还没有看到关于 SO 的正则表达式解决方案来解决这个问题。

您可以将正则表达式表与 python、C++、grep 等中的任何一个一起使用,请记住,许多语言都有多种注释类型,并且某些类型的注释(在某些语言中)可以是多行的。 可以轻松返回行号。

看看 python re 库文档作为起点。

[OP 要求将此作为答案发布]

如果你想处理各种各样的语言,你需要确定它们属于类别(类C,带有C样式注释,COBOL带有COBOL样式注释,...),并为每种语言构建一个词法分析器。如果语言有很多奇怪的词汇语法,那么这种词法分析器的细节可能会变得棘手(PHP在这方面非常粗俗,请查看内插字符串)。

如果你想要一个现成的,我们的源代码搜索引擎通过词法和索引你给它的代码库来提供大规模的搜索;它有大约40+语言和方言的词法分析器;要求它找到所有评论(或任何其他标记)并将它们全部作为搜索命中导出到命中日志文件是微不足道的。(打开日志后的命令实际上是字母"C"[用于注释])。

[回答另一个问题]。 它具有GUI和命令行界面。

根据Ira Baxter的有用建议,我通过搜索词法分析器找到了Pygments。

Pygments理解大量语言,并将其中任何一种语言的输入转换为适合突出显示的标准化HTML输出。

下面获取目录的路径,递归搜索代码文件,并返回文件名和每个文件中的注释的字典:

import glob
import io
import os
import pathlib
import git
from pygments.formatter import Formatter
import pygments
import pygments.lexers

class CommentExtractor(Formatter):
  def __init__(self, **options):
    Formatter.__init__(self, **options)
  def format(self, tokensource, outfile):
    for ttype, value in tokensource:
      if ttype in pygments.token.Comment:
        outfile.write(value)

def GetCommentsFromFile(path):
  lexer = pygments.lexers.get_lexer_for_filename(path)
  comments = io.StringIO()
  pygments.highlight(
    code      = open(path,'r').read(),
    lexer     = lexer,
    formatter = CommentExtractor(), 
    outfile   = comments
  )
  return comments.getvalue()

def GetCommentsFromFiles(rootpath, excluded):
  files = {}
  for (dirpath, dirnames, filenames) in os.walk(rootpath):
    #Skip hidden directories
    dirnames[:] = [d for d in dirnames if not d.startswith('.')]
    for filename in filenames:
      if filename.startswith('.'):       #Skip hidden files
        continue
      if pathlib.Path(filename).suffix in excluded:
        continue
      filename = os.path.join(dirpath, filename)
      try:
        files[filename] = GetCommentsFromFile(filename)
      except pygments.util.ClassNotFound:
        pass
  return files

excluded_files_types = {".md", ".yml", ".bat", ".sh"}
files_and_comments = GetCommentsFromFiles(
  rootpath = "root_of_code_directories",
  excluded = excluded_files_types
)