如何用Python解析C#代码并拆分语句?需忽略注释与字符串
用Python解析C#代码并提取带行号的语句(忽略注释与字符串)
直接基于你已经用到的Pygments CSharpLexer改造就能解决问题,核心思路是过滤掉注释、字符串类的token,再按语句分隔符拼接出完整语句并跟踪行号。下面是可运行的实现:
from pygments.lexers.dotnet import CSharpLexer from pygments.token import Token def extract_csharp_statements(file_path): lexer = CSharpLexer() statements = [] current_stmt = "" current_line = None with open(file_path, 'r', encoding='utf-8') as f: code = f.read() # 遍历所有token,过滤无关内容并拼接语句 for token_type, value, (start_line, _) in lexer.get_tokens_unprocessed(code): # 跳过注释、普通字符串、逐字/多行逐字字符串 if token_type in (Token.Comment, Token.String, Token.Literal.String): continue # 记录当前语句的起始行号 if not current_stmt: current_line = start_line current_stmt += value # 按C#语句分隔符拆分:;、{、} # {和}本身作为代码块标记,单独作为语句单元 if any(current_stmt.endswith(delim) for delim in (';', '{', '}')): trimmed_stmt = current_stmt.strip() if trimmed_stmt: statements.append((trimmed_stmt, current_line)) # 重置当前语句状态 current_stmt = "" current_line = None # 处理最后可能未闭合的语句(比如文件末尾的代码块结束标记) if current_stmt.strip(): statements.append((current_stmt.strip(), current_line)) return statements # 使用示例 if __name__ == "__main__": statements = extract_csharp_statements("test.cs") for stmt, line in statements: print(f"Line {line}: {stmt}")
关键细节说明
- 精准过滤无关内容:借助Pygments的语法解析能力,直接跳过
Token.Comment(单行//、多行/* */)、Token.String系列(普通字符串、@""逐字字符串、@""""多行逐字字符串),避免这些内容里的分隔符被误判。 - 行号准确跟踪:每个语句的行号取第一个有效token的起始行,哪怕语句跨多行,也能正确记录其起始位置。
- 贴合C#语法的拆分逻辑:把
;、{、}都作为语句结束标记,拆分出变量声明、表达式、代码块开闭标记等符合C#语法的完整单元。
这个方案刚好解决你之前的两个痛点:不用自己处理注释和字符串的嵌套识别问题,还能直接得到带行号的语句块,而非零散的token。
内容的提问来源于stack exchange,提问作者Shoo Limberger
相关产品推荐
相关产品推荐

