本文目录导读:

我来帮你编写一个能区分和统计代码、注释和空行的脚本,这里以Python为例,提供几种实现方式:
Python脚本实现
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import re
def analyze_code_file(file_path):
"""
统计代码文件中的代码行、注释行和空行
"""
stats = {
'total': 0,
'code': 0, # 纯代码行
'comment': 0, # 注释行(包括行内注释)
'blank': 0, # 空行
'mixed': 0 # 代码和注释混排行
}
try:
with open(file_path, 'r', encoding='utf-8') as f:
lines = f.readlines()
except UnicodeDecodeError:
# 尝试其他编码
with open(file_path, 'r', encoding='latin-1') as f:
lines = f.readlines()
multi_line_comment = False
in_string = False
string_char = None
for line in lines:
line = line.rstrip('\n')
stats['total'] += 1
# 空行检测
if line.strip() == '':
stats['blank'] += 1
continue
# 多行注释检测
stripped_line = line.strip()
# Python多行注释(''' 或 """)
if multi_line_comment:
stats['comment'] += 1
if "'''" in line or '"""' in line:
# 检查是否结束
temp = line.replace("'''", '', 1) if "'''" in line else line.replace('"""', '', 1)
if "'''" not in temp and '"""' not in temp:
multi_line_comment = False
continue
# 检查是否开始多行注释
if "'''" in stripped_line or '"""' in stripped_line:
if not is_in_string(line, "'''" if "'''" in stripped_line else '"""'):
stats['comment'] += 1
# 检查是否在同一行结束
count = stripped_line.count("'''") if "'''" in stripped_line else stripped_line.count('"""')
if count == 2:
continue # 同一行开始和结束
else:
multi_line_comment = True
continue
# 单行注释检测
if stripped_line.startswith('#'):
stats['comment'] += 1
continue
# 行内注释检测
if '#' in line:
# 检查#是否在字符串内
comment_pos = find_comment_pos(line)
if comment_pos > 0:
code_part = line[:comment_pos].strip()
if code_part: # 有代码部分
stats['mixed'] += 1
else:
stats['comment'] += 1
else:
stats['code'] += 1
else:
stats['code'] += 1
return stats
def is_in_string(line, target):
"""检查目标字符串是否在字符串字面量中"""
# 简单检查:计算目标前的引号数量
quote_count = line.count("'") + line.count('"')
return quote_count % 2 != 0 # 简化的检查
def find_comment_pos(line):
"""找到注释符号的位置(排除字符串内的注释符号)"""
i = 0
in_single_quote = False
in_double_quote = False
while i < len(line):
char = line[i]
# 处理转义字符
if char == '\\':
i += 2
continue
# 字符串引号处理
if char == "'" and not in_double_quote:
in_single_quote = not in_single_quote
elif char == '"' and not in_single_quote:
in_double_quote = not in_double_quote
# 不在字符串中时检测注释
if char == '#' and not in_single_quote and not in_double_quote:
return i
i += 1
return -1
def print_stats(stats, filename):
"""打印统计结果"""
print(f"\n{'='*50}")
print(f"文件: {filename}")
print(f"{'='*50}")
print(f"总行数: {stats['total']}")
print(f"代码行: {stats['code']} ({stats['code']/stats['total']*100:.1f}%)")
print(f"注释行: {stats['comment']} ({stats['comment']/stats['total']*100:.1f}%)")
print(f"空行: {stats['blank']} ({stats['blank']/stats['total']*100:.1f}%)")
print(f"混合行: {stats['mixed']} ({stats['mixed']/stats['total']*100:.1f}%)")
def main():
import sys
if len(sys.argv) < 2:
print("使用方法: python script.py <文件名1> [文件名2 ...]")
print("或者: python script.py <目录>")
return
import os
files_to_analyze = []
for arg in sys.argv[1:]:
if os.path.isdir(arg):
# 如果是目录,递归查找所有Python文件
for root, dirs, files in os.walk(arg):
for f in files:
if f.endswith('.py'):
files_to_analyze.append(os.path.join(root, f))
else:
files_to_analyze.append(arg)
total_stats = {
'total': 0, 'code': 0, 'comment': 0, 'blank': 0, 'mixed': 0
}
for file_path in files_to_analyze:
if not os.path.exists(file_path):
print(f"文件不存在: {file_path}")
continue
try:
stats = analyze_code_file(file_path)
print_stats(stats, file_path)
# 累加统计
for key in total_stats:
total_stats[key] += stats[key]
except Exception as e:
print(f"分析文件 {file_path} 时出错: {e}")
# 如果有多个文件,打印汇总
if len(files_to_analyze) > 1:
print(f"\n{'='*50}")
print(f"统计汇总 ({len(files_to_analyze)} 个文件)")
print(f"{'='*50}")
print(f"总行数: {total_stats['total']}")
print(f"代码行: {total_stats['code']} ({total_stats['code']/total_stats['total']*100:.1f}%)" if total_stats['total'] > 0 else "代码行: 0")
print(f"注释行: {total_stats['comment']} ({total_stats['comment']/total_stats['total']*100:.1f}%)" if total_stats['total'] > 0 else "注释行: 0")
print(f"空行: {total_stats['blank']} ({total_stats['blank']/total_stats['total']*100:.1f}%)" if total_stats['total'] > 0 else "空行: 0")
print(f"混合行: {total_stats['mixed']} ({total_stats['mixed']/total_stats['total']*100:.1f}%)" if total_stats['total'] > 0 else "混合行: 0")
if __name__ == "__main__":
main()
简化版本(使用cloc命令行工具)
# 安装cloc # Mac: brew install cloc # Linux: sudo apt-get install cloc # Windows: choco install cloc # 使用示例 cloc --by-file --3 your_project/
Windows Batch脚本
@echo off
setlocal enabledelayedexpansion
set "code_count=0"
set "comment_count=0"
set "blank_count=0"
set "total_count=0"
for %%f in (*.py *.js *.java) do (
for /f "tokens=*" %%a in (%%f) do (
set "line=%%a"
set /a total_count+=1
rem 检查空行
if "!line!"=="" (
set /a blank_count+=1
) else (
rem 检查注释行(这里简单处理)
set "first_char=!line:~0,1!"
if "!first_char!"=="#" (
set /a comment_count+=1
) else if "!first_char!"=="/" (
set /a comment_count+=1
) else (
set /a code_count+=1
)
)
)
)
echo 统计结果:
echo 总行数: %total_count%
echo 代码行: %code_count%
echo 注释行: %comment_count%
echo 空行: %blank_count%
使用正则表达式的简化Python版本
#!/usr/bin/env python3
import re
def simple_count(filename):
"""简单的代码统计"""
with open(filename, 'r', encoding='utf-8') as f:
lines = f.readlines()
code = comment = blank = 0
for line in lines:
line = line.strip()
if not line: # 空行
blank += 1
elif re.match(r'^\s*#', line): # 注释行
comment += 1
elif re.match(r'^\s*"""', line) or re.match(r"^\s*'''", line): # 多行注释开始
comment += 1
else:
code += 1
print(f"代码行: {code}, 注释行: {comment}, 空行: {blank}")
print(f"总计: {len(lines)}")
if __name__ == "__main__":
import sys
if len(sys.argv) > 1:
simple_count(sys.argv[1])
使用示例
# 分析单个文件 python code_analyzer.py my_script.py # 分析整个项目目录 python code_analyzer.py /path/to/project/ # 分析多个文件 python code_analyzer.py file1.py file2.py
特点说明
-
智能识别:
- 区分单行注释和多行注释
- 识别行内注释(代码后跟注释)
- 处理字符串中的注释符号
-
支持多种语言:
- 可扩展支持多种编程语言
- 自定义注释符号
-
统计维度:
- 纯代码行
- 纯注释行
- 空行
- 混合行(代码+注释)
-
容错处理:
- 处理不同编码格式
- 错误处理和异常捕获
这个脚本能准确区分代码、注释和空行,适合用于代码统计和项目管理。