目前的编辑器大都可以自动检测某一行代码是否为代码行或注释行,但并不太提供代码行/注释行行数的统计,对于大量代码文件的代码行/注释行统计,就更少见一些。本篇文章试用一段Python脚本来实现这一目标,并希望可以兼容统计不同语言编写的代码。

注释符号的研究

我们先来关注常见语言的注释符号构成。一般来讲注释符号分为单行注释符和多行注释符,以Python为例,则分别为#和'''(或""")。由于多行注释符会影响后续行的判断,所以在遍历各行时必须存在一个标志位multiCmtFlagIdx,来记录是否已经开始多行注释,以及多行注释的符号为哪一种。有了该判断之后,才可以继续对后续的字符进行分析。

1. 在多行注释中

这种情况后面的分析较为简单,由于已知多行注释符的类型,我们可以判断后续的字符中最早出现对应的多行注释结束符的位置为:

如果可以搜索到,则将multiCmtFlagIdx赋值为-1,表示多行注释已经结束。如果没有搜索到,则说明本行后续字符仍在多行注释中,可以直接开始下一行的解析。

2. 不在多行注释中

对于这种情况,如果后续字符中除了空格和制表符,首先出现的是单行注释符,则注释符后面的字符都在注释中,所以可以直接结束本行的解析,开始下一行。否则,我们需要继续搜索多行注释开始符出现的位置。

找到多行注释开始符后,并不意味着后面就是注释内容,还需要做两点检查:

1)该注释符是否在引号对中,因为此时在引号中的注释符是不起作用的;

2)该注释符是否是最早出现的多行注释开始符类型,由于同一种语言的多行注释符可能有多种,而只有最早出现的多行注释开始符才起作用。

1)针对第一点,我们可以在搜索的起点到该注释符的区间内计算引号的数量,如果引号为偶数,则说明不在引号对中,否则在引号对中。

引号数量奇偶性判断,需要逐对来判断,这是因为引号对中的引号是不起作用的。有一种特例是,多行注释符同时也是引号的组合,例如Python。此时计算数量的引号,需要与搜索到的多行注释符不同,如多行注释符为''',则应该计算"的数量。

2)针对第二点,我们可以遍历各个多行注释开始符,并取位置最靠前的开始符,然后查找对应的结束符。

代码实现

\# encoding: utf-8

import re

'''

isCmt

功能:判断一行字符串是否为注释

输入:

line: 字符串行

isInMultiCmt:前面一行是否在多行注释中

qttnFlagList: 引号列表

输出:

isCmt: 当前行是否为注释

isInMultiCmt:当前行是否在多行注释中

'''

def isCmt(line, multiCmtFlagIdx, cmtFlagObj):

singleCmtFlag = cmtFlagObj["singleCmtFlag"] #单行注释符号

multiCmtFlagList =cmtFlagObj["multiCmtFlagList"]

qttnFlagList = cmtFlagObj["qttnFlagList"] #引号列表

startPos = 0 #搜索多行注释符的开始位置

isCmtRet = True

# print 'line: ' + line.strip()

while startPos < len(line): #查找注释符号直到行末

if multiCmtFlagIdx == -1: #不在多行注释中

minStartIdx = len(line) #搜索到最靠前的多行注释符

if singleCmtFlag != '' and re.match(r'(\s)*' + singleCmtFlag, line[startPos:]): #单行注释

break

idx = 0

preStartIdx = startPos #记录搜索多行注释符前的搜索位置

while idx < len(cmtFlagObj["multiCmtFlagList"]):

startCmtFlag = cmtFlagObj["multiCmtFlagList"][idx][0] #多行注释开始符号

if startCmtFlag == '':

return False, -1 #无多行注释符号

try:

startPos = re.search(r'(?

if isInQuotation(line[:startPos], startCmtFlag, qttnFlagList): #注释开始符在引号中

startPos += len(startCmtFlag.replace('\*', '*')) #找下一个多行注释开始符

continue

else: #注释符号不在引号中

startPos += len(startCmtFlag.replace('\*', '*'))

if startPos < minStartIdx:

multiCmtFlagIdx = idx #是多行注释

minStartIdx = startPos

startPos = preStartIdx #找下一个多行注释开始符

idx += 1

except:

idx += 1

continue #没有找到多行注释开始符,继续查找下个类型的符号

if minStartIdx != len(line): #此时搜索到了多行注释开始符

startCmtFlag = cmtFlagObj["multiCmtFlagList"][multiCmtFlagIdx][0]

if not re.match(r'(\s)*' + startCmtFlag, line[preStartIdx:]):

isCmtRet = False

elif line[preStartIdx:] != '\n':

isCmtRet = False

startPos = minStartIdx

elif multiCmtFlagIdx != -1: #在多行注释中

endCmtFlag = cmtFlagObj["multiCmtFlagList"][multiCmtFlagIdx][1] #多行注释开始符

if endCmtFlag == '':

return False, -1 #注释符号配置有错误

try:

startPos \

= re.search(endCmtFlag, line[startPos:]).start() \

+ startPos \

+ len(endCmtFlag.replace('\*', '*')) #查找多汗注释结束符的位置

multiCmtFlagIdx = -1

except:

break

# print isCmtRet, multiCmtFlagIdx

return isCmtRet, multiCmtFlagIdx #返回是否注释行,以及当前是否在多行注释中

'''

函数名:isInQuotation

功能:根据字符串中引号的奇偶,判断后面的字符是否在引号中

输入:

line: 一行代码中指定字符前的字符串

qttnFlagList: 引号列表

输出:

布尔值:

True:字符串包含在引号中

False:字符串不包含在引号中

'''

def isInQuotation(line, cmtFlag, qttnFlagList):

qttnFlagIdx = len(line)

flagIdx = len(line)

rearLine = line

for i in range(len(qttnFlagList)):

flag = qttnFlagList[i]

if flag == cmtFlag[0]: #排除引号同时也是注释符号的情况

continue

try:

flagIdx = re.search(r'(?

rearLine = re.search(r'(?

except:

flagIdx = len(line)

if flagIdx < qttnFlagIdx: #根据最早出现的左引号,确认左引号类型

qttnFlagIdx = flagIdx

qttnFlag = flag

if qttnFlagIdx != len(line):

try:

#print rearLine

rearLine = re.search(r'(?

return isInQuotation(rearLine, cmtFlag[0], qttnFlagList) #再次查找下一个左引号

except:

return True #在引号对中

else:

return False #不在引号对中

以上这篇Python实现判断一行代码是否为注释的方法就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持脚本之家。

python怎么返回上一行代码_Python实现判断一行代码是否为注释的方法相关推荐

  1. python里面返回上一步_Python中的这3个骚操作你会吗?

    本文主要介绍Python的高级特性:列表推导式.迭代器和生成器,是面试中经常会被问到的特性. 因为生成器实现了迭代器协议,可由列表推导式来生成,所有,这三个概念作为一章来介绍,是最便于大家理解的,现在 ...

  2. python字符串是否包含某元素_Python实现判断一个字符串是否包含子串的方法总结...

    本文实例总结了Python实现判断一个字符串是否包含子串的方法.分享给大家供大家参考,具体如下: 1.使用成员操作符 in >>> s='nihao,shijie' >> ...

  3. vue中如何点击返回上一页,vue判断没有上页返回首页

    vue中如何点击返回上一页,vue判断没有上页返回首页 vue中返回上一页 // 返回 returnBtn(){this.$router.go(-1); }, 返回上一页,先判断是否有上一页,没有则返 ...

  4. python如何撤销上一步_python代码运行到某一步能返回到前面某一步吗?

    展开全部 有. Eclipse里编程代码,返回上一步的快捷键是636f70793231313335323631343130323136353331333365653261alt+←箭头. eclips ...

  5. python中撤回上一步_python返回上一步

    python代码运行到某一步能返回到前面某一步吗? 有. Eclipse里编程代码,返回上一步的快捷键是alt+←箭头. eclipse中几个最重要的快捷键. 代码助手:Ctrl+Space(简体中文 ...

  6. python中返回上一步操作_通过实例解析Python文件操作实现步骤

    当程序运行时,变量是保存数据的好方法,但变量.序列以及对象中存储的数据是暂时的,程序结束后就会丢失,如果希望程序结束后数据仍然保持,就需要将数据保存到文件中. Python 提供了内置的文件对象,以及 ...

  7. python英文词频统计代码_python实现中文和英文的词频统计功能方法汇总

    python的思维就是让我们用尽可能少的代码来解决问题.对于词频的统计,就代码层面而言,实现的方式也是有很多种的.之所以单独谈到统计词频这个问题,是因为它在统计和数据挖掘方面经常会用到,尤其是处理分类 ...

  8. python函数返回多个值_python函数返回多个值的示例方法

    python可以返回多个值,确实挺方便 函数里的return只能返回一个值,但是返回类型是没是限制的 因此,我们可以"返回一个 tuple类型,来间接达到返回多个值". 例子是我在 ...

  9. 网页上的“返回上一页”的几种实现代码

    在制作网页的时候,经常在网页上要用到"返回上一页"的功能. 这一功能在制作网页的时候会有多种编码方法,在此, 我将比较常用的几种编码的写作方法在下面列出来,供参考使用. 方法一.以 ...

最新文章

  1. 2017-1-11 css3布局
  2. clr enabled Server Configuration Option
  3. aix系统服务器限制ftp访问,AIX 限制ftp用户只能访问其主目录
  4. wordpress使用retro方案出现413 Request Entity Too Large(Activate还是有问题)
  5. Zigbee如何在智能家居中成为领先的连接技术?
  6. Android广播接实现电话的监听(电话的状态,拦截)
  7. 2016 hctf fheap 题解
  8. linux间隔一定时间访问指定url
  9. 将表中的数据生成SQL脚本,在查询分析器中执行这些脚本后自动将数据导入到SQL Server中...
  10. ubuntu 16.04安装并启动openssh
  11. 电脑误删文件硬盘U盘内存卡数据修复---EasyRecovery恢复
  12. win8.1安装马上6,连不上
  13. bootice添加黑苹果引导_Clover Configurator黑苹果 Clover 引导配置工具
  14. dota2 自定义官方服务器,起源2引擎DOTA2重生设置 自定义房间创建
  15. 《HarmonyOS开发 – 小凌派-RK2206开发笔记》第5章 使用WiFi联网
  16. Python向已有数据的Excel表写入数据
  17. pandas学习之电影评分(利用python进行统计分析)的学习笔记
  18. Xenserver命令大全
  19. 面向对象系列(二)-封装,继承,多态
  20. 推荐的前端开源项目CDN加速服务

热门文章

  1. react+ant练习
  2. 错过校招_您可能错过的Web优化技巧
  3. 音乐雷达 shazam算法_具有10亿首Shazam音乐识别功能的数据可视化
  4. java中super关键字的用法
  5. java压缩传输_简单实现字符串的压缩,减轻传输压力
  6. scheme http https 区别 tls_HTTPS、HTTP、TLS/SSL工作及握手原理、PKI/CA密钥体系
  7. ubuntu命令之dpkg
  8. 关于静摩擦与动摩擦的loop_up_table设置
  9. Python学习笔记之常用模块总结,持续更新...
  10. 尝试对知乎网验证码进行处理: