脚本如何区分统计代码注释空行

wen 实用脚本 30

本文目录导读:

脚本如何区分统计代码注释空行

  1. Python脚本实现
  2. 简化版本(使用cloc命令行工具)
  3. Windows Batch脚本
  4. 使用正则表达式的简化Python版本
  5. 使用示例
  6. 特点说明

我来帮你编写一个能区分和统计代码、注释和空行的脚本,这里以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

特点说明

  1. 智能识别

    • 区分单行注释和多行注释
    • 识别行内注释(代码后跟注释)
    • 处理字符串中的注释符号
  2. 支持多种语言

    • 可扩展支持多种编程语言
    • 自定义注释符号
  3. 统计维度

    • 纯代码行
    • 纯注释行
    • 空行
    • 混合行(代码+注释)
  4. 容错处理

    • 处理不同编码格式
    • 错误处理和异常捕获

这个脚本能准确区分代码、注释和空行,适合用于代码统计和项目管理。

抱歉,评论功能暂时关闭!