近日因为种种缘由,须要把代码里面的类所有都修改一遍类名。python
在网上找了一圈相关的开源库,没有发现有合适满意的,始终都存在一些问题,要么出现误修改,要么把方法名或者属性名也给修改了等等状况。git
因而决定掏出生疏的Python来写一个。程序员
批量修改类名须要解决四个问题:github
因为本身前不久写了一个获取target对应的编译以及资源文件的工具MacPbxprojHelper,利用其来获取到target对应的类名写入文件,而后用python来读取文件获取到须要修改的类名,实时上初版我也是这么作的,可是不够优雅,明明一个脚本能解决的事,为何须要那么多步操做呢?数组
利用python直接遍历文件夹获取类名,没错就决定是你了。 其实用python遍历文件实现起来特别简单快捷。可是其中也有可能存在的问题,例如咱们的项目中包含有部分资源文件,而资源文件的后缀名是不定的,可是实际咱们只须要.m以及.mm结尾的文件前缀做为咱们的类名,固然其中包含有类目也须要过滤掉。而且考虑到咱们具有一些特殊的需求,须要过滤某些文件甚至某些文件夹下的文件等等。我这边的脚本都有考虑到xcode
实现代码以下:bash
def getClassNames(filepath):
#读取文件名入数组
#过滤文件夹
filterDirs = ["ThirdKit/","小说/"]
#过滤文件
filterFiles = []
classNames = []
#遍历filepath下全部文件,包括子目录
for root, dirs, files in os.walk(filepath):
for name in files:
path = os.path.join(root, name)
#过滤文件夹
isFilterDir = 0
for filterDir in filterDirs:
if filterDir in path:
isFilterDir = 1
break
if isFilterDir != 1:
if ".m" in name:
splitNames = name.split(".m")
#只选择.m和.mm结尾的文件
if splitNames[1] == "" or splitNames[1] == "m":
cn = splitNames[0]
#过滤文件
isFilterFile = 0
for ff in filterFiles:
if ff == cn:
isFilterFile = 1
if isFilterFile != 1:
#过滤类目
if cn.find("+") == -1:
print(cn)
classNames.append(cn)
return classNames
复制代码
在我搜集到的开源的脚本中,有极大比例的一部分是直接经过类名替换,其实这特别容易出现误改。好比我有一个类名为ABC,一个类名为AB,那么ABC就可能出现被修改两次的状况。因此我这边就采用笨办法,先敲定类名出现的场景,根据其场景设定规则,只有出现类名出如今这些规则中时,才去替换,这样就能够保证100%的正确率。(这也是大坑,由于不一样的程序员书写习惯的问题,致使规则的定义实际极度繁琐,并且会出现部分遗漏,每一次遗漏后,我都须要添加规则再重跑来验证··)app
下面就是这个脚本最大的贡献·· 自认为基本涵盖完了类名的出现场景(若是有没有涵盖的,请记得必定联系我!!),一共37种规则,运用这37种规则,作到了一次脚本,既完美修改,无需在动代码就能够直接运行而且不会有闪退问题··工具
#一开始构思了 14个 后来....
rule_1 = '"' + cn + '.' #引用修改
rule_2 = '"' + cn + '"' #类名被直接使用
rule_3 = ':' + cn + ' ' #继承 后续有空格
rule_4 = ':' + cn + '\n' #类名后面是换行
rule_5 = ' ' + cn + '<'
rule_6 = ' ' + cn + '\n' #类名后面是换行
rule_7 = ' ' + cn + ' '
rule_8 = ' ' + cn + '('
rule_9 = '[' + cn + ' '
rule_10 = '[' + cn + '*'
rule_11 = '(' + cn + '*'
rule_12 = ')' + cn + '*'
rule_13 = ' ' + cn + '*'
rule_14 = ' ' + cn + '\n'
rule_15 = '(' + cn + ' '
rule_16 = ' ' + cn + ';'
rule_17 = ',' + cn + ' '
rule_18 = ',' + cn + '*'
rule_19 = ')' + cn + ' '
rule_20 = ',' + cn + ';'
rule_21 = ' ' + cn + ','
rule_22 = '<' + cn + '*' #被当作协议 遵照类
rule_23 = '<' + cn + ' '
rule_24 = ',' + cn + ','
rule_25 = ' ' + cn + ':'
rule_26 = ':' + cn + '//' #后面跟注释的、、我TM。。
rule_27 = ' ' + cn + '//'
rule_28 = ' ' + cn + '{' #后面跟大括号的··
rule_29 = ')' + cn + '<' #为何遵照协议 也用了 实际类名 没有用ID
rule_30 = '(' + cn + '.' #为何类要使用.语法
rule_31 = ' ' + cn + '.' #类名调用.语法
rule_32 = '!' + cn + '.'
rule_33 = ':' + cn + '.' #类名调用点语法 被当作参数传入
rule_34 = '[' + cn + '\n' #类名被换行
rule_35 = ':' + cn + '<' #继承类名后面 直接接入协议 默认实际是不存在这个问题的
rule_36 = '"' + cn + '_' #类取名有下划线以及数字 以及经过工厂用数字来建立的状况
rule_37 = '"' + cn + '%' #类取名有数字 以及经过工厂用数字来建立的状况
复制代码
这个问题其实很好解决,利用python的os库就能够直接rename,只是须要拼接全路径。而且在给类文件重命名的时,须要注意前缀和后缀添加的位置,不要添加到.h和.m后面去了便可。ui
这里又和第二个问题同样须要定义必定规则,才能确保不会出现误替换,可是这个规则和上面比起来简直是小巫见大巫。规则以下:
def pbRule(cn):
rule_1 = '=' + cn + "."
rule_2 = ' ' + cn + "."
rule_3 = '/' + cn + "."
rule_4 = '"' + cn + "."
复制代码
以上,问题都解决了。
----------脚本说明----------
脚本用于批量修改类名
脚本可传入四个参数
一、待处理的文件路径. example-->'./KanManHua'
二、待修改的pbxproj文件地址 example-- >'./KanManHua.xcodeproj/project.pbxproj'
三、类名前缀 example-->'MHT_'
四、类名后缀 example-->'_MHT'
其中前三个参数为必传参数 划重点,要考
----------请开心使用---------
另脚本支持 -h --help 操做
复制代码
当参数错误时,也有对应提示以及上述帮助信息
示例:
python changeClassName.py ./KanManHua ./KanManHua.xcodeproj/project.pbxproj MHT_ _MHT
复制代码
示例:
python changeClassName.py
python changeClassName.py -h
python changeClassName.py --help
复制代码
因为我司还有需求修改指定 target的类名,实际也有一套能够仅仅只修改target类名的方法,可是因为使用要复杂一点,首先要提取target对应的编译类,再使用脚原本修改,修改使用到我以前发布的一个工具类MacPbxprojHelper,若有须要的话请和我联系。 联系方式:357863248@qq.com