python匹配类体或函数体,用以插入代码

把下面的python脚本保存为 code_analyze.py

# -*- coding:utf-8 -*-
#import re

def delete_comm(str_ = ""):
    "删除C语言上的 /* */ 与 // 的注释的代码"
    need_ = True
    while need_:
        need_ = False
        str_ = str_.strip()
        str_len = len(str_)
        i = 0
        while (i < str_len and i < 3000):
            c = str_[i]
            if c == '"':
                i += 1
                while i < str_len:
                    c2 = str_[i]
                    if c2 == '"':
                        break
                    elif c2 == '\\':
                        i += 1
                    i += 1
                i += 1
            elif c == '/':
                f_c = i
                i += 1
                if i > str_len:
                    break
                if str_[i] == '/':
                    f = str_.find('\n', i)
                    if f < i:
                        return str_[0, f_c]
                    i = f + 1
                    str_ = str_[:f_c] + str_[i:]
                    str_len = len(str_)
                    need_ = True
                    break
                elif str_[i] == '*':
                    f = str_.find("*/", i)
                    if f < i:
                        return str_
                    i = f + 2
                    str_ = str_[:f_c]+str_[i:]
                    need_ = True
                    break
            else:
                i += 1
    return str_

def is_space(c):
    return c == ' ' or c == '\t' or c == '\r' or c == '\n'

def slice_to_idx_ls(text='', start_bk='(',start_pos = 0):
    right_to_left = {'}':'{', ']' : '[' , ')':'('}
    res = []
    i = start_pos
    ix = text.find(start_bk, i)
    if (ix < i ) and (ix > len(text)):
        return None
    i = ix
    bk_stack = []
    bk_stack.append(start_bk)
    res.append(i)
    i += 1
    while is_space(text[i]):
        i += 1
    while i < len(text):
        c = text[i]
        if c == '{' or c == '[' or c == '(':
            bk_stack.append(c)
            i += 1
        elif c == '}' or c == ']' or c == ')':
            if bk_stack[-1] != right_to_left[c]:
                return None
            bk_stack = bk_stack[:-1]
            if len(bk_stack) == 0:
                res.append(i)
                return res    
            i += 1
            while is_space(text[i]):
                i += 1
        elif c == '/':
            i += 1
            c2 = text[i]
            if c2 == '/':
                ix = text.find('\n', i)
                i = ix + 1
            elif c2 == '*':
                ix = text.find('*/',i)
                i = ix + 2
        elif c == '"':
            i += 1
            while i < len(text):
                c2 = text[i]
                if c2 == '\\':
                    i += 1
                elif c2 == '"':
                    break
                i+=1
            i+=1
        elif c == ',':
            if len(bk_stack) == 1:
                res.append(i)
            i += 1
        else:
            i += 1
    return None

def split_args(text, start_bk = '(', start_pos = 0):
    "切分如同 func_name(a, \"ww,ww\" , b(function(){}), c() ) 这类的文本,成['func_name', 'a', ' \"ww,ww\" ', ' b(function(){})', ' c() '] "
    sl = slice_to_idx_ls(text, start_bk, start_pos)
    if not sl:
        return None
    res = []
    lst = start_pos
    text_len = len(text)
    for cur in sl:
        if lst > text_len or cur > text_len or lst < 0 or cur - lst < 0:
            raise "split_args:ERROR:unknown"
        res.append(text[lst: cur])
        lst = cur + 1

    return res
def set_str_value(text, start_mark, start_pos, value):
    idx = text.find(start_mark, start_pos)
    if idx < 0:
         return False
        
    len_text = len(text)
    i = idx + len(start_mark)
    idx1 = -1
    idx2 = -1
    while i < len_text:
        c = text[i]
        if c == '/':
            i += 1
            c2 = text[i]
            if c2 == '/':
                ix = text.find('\n', i)
                if ix < i:
                    return False
                i = ix + 1
            elif c2 == '*':
                ix = text.find('*/', i)
                if ix < i:
                    return False
                i = ix + 2
        elif c == '"':
            idx1 = i
            i += 1
            while i < len_text:
                c2 = text[i]
                if c2 == '\\':
                    i += 1
                elif c2 == '"':
                    idx2 = i
                    break
                i+=1
            i+=1  
        elif c == '\'':
            idx1 = i
            i += 1
            while i < len_text:
                c2 = text[i]
                if c2 == '\\':
                    i += 1
                elif c2 == '\'':
                    idx2 = i
                    break
                i+=1
            i+=1
        elif is_space(c):
            i+=1
        else:
            return False
        if idx1 != -1 and idx2 != -1:
            break
    if idx1 != -1 and idx2 != -1:
        return text[:idx1+1]+value+text[idx2:]
    return False

def find_a_string_idx(text,  start_pos):
    idx = start_pos
    if idx < 0:
         return False
    len_text = len(text)
    i = idx
    idx1 = -1
    idx2 = -1
    while i < len_text:
        c = text[i]
        if c == '/':
            i += 1
            c2 = text[i]
            if c2 == '/':
                ix = text.find('\n', i)
                if ix < i:
                    return None
                i = ix + 1
            elif c2 == '*':
                ix = text.find('*/', i)
                if ix < i:
                    return None
                i = ix + 2
        elif c == '"':
            idx1 = i
            i += 1
            while i < len_text:
                c2 = text[i]
                if c2 == '\\':
                    i += 1
                elif c2 == '"':
                    idx2 = i
                    break
                i+=1
            i+=1  
        elif c == '\'':
            idx1 = i
            i += 1
            while i < len_text:
                c2 = text[i]
                if c2 == '\\':
                    i += 1
                elif c2 == '\'':
                    idx2 = i
                    break
                i+=1
            i+=1
        else:
            i+=1

        if idx1 != -1 and idx2 != -1:
            break
    if idx1 != -1 and idx2 != -1:
        return (idx1, idx2)
    return False

def find_all_string_pos(txt, start_pos=0):
    pos_ls = []
    txt_pos = start_pos
    txt_len = len(txt)
    if txt_pos >= txt_len:
        return None
    while True:
        pos_ = find_a_string_idx(txt, txt_pos)
        if not pos_:
            break
        pos_ls.append(pos_)
        txt_pos = pos_[1] +1
    if not pos_ls:
        return None
    return pos_ls

def find_all_string(txt, start_pos=0):
    pos_ls = find_all_string_pos(txt, start_pos)
    if not pos_ls:
        return None
    ls = []
    for pos_ in pos_ls:
        ls.append(txt[pos_[0]:pos_[1]+1])
    return ls

#print delete_comm(r'''(abc/*adefe*/, "adefe"//daefafe
#   faeifdjk=() )''')
#print split_args( '( wde, abde ,  "cdf,geg" , efg(function(){ }) )' )
#print split_args('fdafeat[ wde, abde ,  "cdf,geg" , efg(function(){ }) ]', '[')
#print split_args("func_name(a, \"ww,ww\" , b(function(){}), c() )")
#print split_args("this.static = []", '[')
#print set_str_value(' t=""  ', 't=' , 0, 'abc')
#print set_str_value(' t=   " "  ', 't=',0, 'abc')
#print set_str_value(' t=""  ', 't=' , 0, 'abc')
#print set_str_value(' t=/*wwww*/" "  ', 't=',0, 'abc')
#print set_str_value(' t="\'"  ', 't=' , 0, 'abc')
#print set_str_value(' t=   " "  ', 't=',0, 'abc')
#print set_str_value(' t="\\\"\\\""  ', 't=' , 0, 'abc')
#print set_str_value(' t="/*wwww*/"  ', 't=',0, 'abc')
#print set_str_value(' t=\'\'  ', 't=' , 0, 'abc')
#print set_str_value(' t=   \' \'  ', 't=',0, 'abc')
#print set_str_value(' t=\'\" \'', 't=' , 0, 'abc')

然后在同级目录中,我们创建一个测试的python脚本:test.py

import code_analyze
#import re

txt = """

public class ABC2 : DDD
{
    // 加入一些干扰{}}.}\|}{
    /*}*/
    void a() { }

    void b()
    {
       if (true)
       {
          Debug.Log("bbbbbbb");
       }
    }
}

public class HHHH
{
    void a() { }

    void b()
    {
        Debug.Log("aaaaaaaa");
    }
}
"""

def test():
    mark = 'public class ABC2 : DDD'
    idx = txt.find(mark)
    if idx<0:
        print('not found mark:'+mark)
        return
    ls = code_analyze.slice_to_idx_ls(txt, '{', idx)
    vidx = ls[-1]
    # 插入一个Hello函数
    print ( txt[:vidx] +  "\n    void Hello(){}\n"+txt[vidx:])
     
test()

测试结果如下
python匹配类体或函数体,用以插入代码_第1张图片

你可能感兴趣的:(python)