国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > Python > 正文

Python實現判斷一行代碼是否為注釋的方法

2020-02-23 00:13:10
字體:
來源:轉載
供稿:網友

目前的編輯器大都可以自動檢測某一行代碼是否為代碼行或注釋行,但并不太提供代碼行/注釋行行數的統計,對于大量代碼文件的代碼行/注釋行統計,就更少見一些。本篇文章試用一段Python腳本來實現這一目標,并希望可以兼容統計不同語言編寫的代碼。

注釋符號的研究

我們先來關注常見語言的注釋符號構成。一般來講注釋符號分為單行注釋符和多行注釋符,以Python為例,則分別為#和'''(或""")。由于多行注釋符會影響后續行的判斷,所以在遍歷各行時必須存在一個標志位multiCmtFlagIdx,來記錄是否已經開始多行注釋,以及多行注釋的符號為哪一種。有了該判斷之后,才可以繼續對后續的字符進行分析。

1. 在多行注釋中

這種情況后面的分析較為簡單,由于已知多行注釋符的類型,我們可以判斷后續的字符中最早出現對應的多行注釋結束符的位置為:

如果可以搜索到,則將multiCmtFlagIdx賦值為-1,表示多行注釋已經結束。如果沒有搜索到,則說明本行后續字符仍在多行注釋中,可以直接開始下一行的解析。

2. 不在多行注釋中

對于這種情況,如果后續字符中除了空格和制表符,首先出現的是單行注釋符,則注釋符后面的字符都在注釋中,所以可以直接結束本行的解析,開始下一行。否則,我們需要繼續搜索多行注釋開始符出現的位置。

找到多行注釋開始符后,并不意味著后面就是注釋內容,還需要做兩點檢查:

1)該注釋符是否在引號對中,因為此時在引號中的注釋符是不起作用的;

2)該注釋符是否是最早出現的多行注釋開始符類型,由于同一種語言的多行注釋符可能有多種,而只有最早出現的多行注釋開始符才起作用。

1)針對第一點,我們可以在搜索的起點到該注釋符的區間內計算引號的數量,如果引號為偶數,則說明不在引號對中,否則在引號對中。

引號數量奇偶性判斷,需要逐對來判斷,這是因為引號對中的引號是不起作用的。有一種特例是,多行注釋符同時也是引號的組合,例如Python。此時計算數量的引號,需要與搜索到的多行注釋符不同,如多行注釋符為''',則應該計算"的數量。

2)針對第二點,我們可以遍歷各個多行注釋開始符,并取位置最靠前的開始符,然后查找對應的結束符。

代碼實現

/# encoding: utf-8import 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'(?<!//)' + startCmtFlag, line[startPos:]).start() + startPos #找到多行注釋開始符號     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'(?<!//)' + flag + r'.*', line).start() #查找左引號   rearLine = re.search(r'(?<!//)' + flag + r'.*', line).group()[len(flag):]  except:   flagIdx = len(line)  if flagIdx < qttnFlagIdx: #根據最早出現的左引號,確認左引號類型   qttnFlagIdx = flagIdx   qttnFlag = flag if qttnFlagIdx != len(line):  try:   #print rearLine   rearLine = re.search(r'(?<!//)' + qttnFlag + r'.*', rearLine).group()[len(qttnFlag):] #查找右引號   return isInQuotation(rearLine, cmtFlag[0], qttnFlagList) #再次查找下一個左引號  except:   return True #在引號對中 else:  return False #不在引號對中            
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 衡阳市| 卫辉市| 瓦房店市| 荣昌县| 成武县| 阿克| 花莲市| 泸水县| 兴仁县| 安达市| 会同县| 酉阳| 丰镇市| 信宜市| 黑山县| 南澳县| 衡山县| 泰州市| 南汇区| 连山| 黄浦区| 滦南县| 银川市| 抚宁县| 理塘县| 凉城县| 新乡市| 郁南县| 高阳县| 吴江市| 湖口县| 聊城市| 祁阳县| 额济纳旗| 平江县| 克山县| 揭东县| 旅游| 公安县| 攀枝花市| 达拉特旗|