公司的N手代码突然要做国际化了,但是之前的架构完全木有考虑到国际化啊,各种中文文本各种散乱地写死在各个文件啊。
怎么办?一个个查找然后手动抽取到.strings文件中?不不不,面对几十万行的代码上千个文件,这样做非要了我狗命不可。
绝望中看到了jasonblog大神的https://blog.youkuaiyun.com/jasonblog/article/details/7310629这个博客。
看到了用python提取中文字串的希望。
很遗憾jasonblog提供的代码只支持将@"中文"转换为NSLocalizedString(@"中文", nil),没有将 "中文" = "中文" 这样的字串写到.strings文件而且没有检查该字符串是否已经加了NSLocalizedString宏。
秉着自己动手丰衣足食的理念,我对jasonblog的代码进行部分补充,最后成功提取出了所有散乱各地的中文文本,捡回一条狗命。
下面贴上源代码:
#!/usr/bin/python
# -*- coding: utf-8 -*-
import os
import re
import codecs
import mmap
import sys
reload(sys)
sys.setdefaultencoding('utf8')
targetPattern = re.compile('@"[^"]+"')
global newFile, newFilePointer, stringFile, stringFilePointer
def isChineseCharacter(ch):
return 0x4e00 <= ord(ch) <= 0x9fff
def hasChineseCharacter(str):
for char in str:
if isChineseCharacter(char):
return True
return False
def findStringInStringFile(string):
global stringFilePointer
stringFilePointer.seek(0,0)
allStr = stringFilePointer.read()
return allStr.find(string)
def buildNewString(oldStr):
newStrPrefix = 'NSLocalizedString('
newStrSuffix = ', nil)'
newStr = newStrPrefix + oldStr + newStrSuffix
return newStr
def processLine(line):
global newFile, newFilePointer, stringFile, stringFilePointer
matchResult = targetPattern.findall(line)
for result in matchResult:
if hasChineseCharacter(result) and line.find('Log('+result)==-1 and line.find('NSLocalizedString('+result)==-1:
line = line.replace(result, buildNewString(result))
subResult = result[1:]
if findStringInStringFile(subResult) == -1:
keyValueString = subResult + ' = ' + subResult + ';\n'
stringFilePointer.seek(0,2)
stringFilePointer.write(keyValueString)
newFilePointer.write(line)
def processFile(dirpath, filename):
#Xcode file is saved with utf-8
global newFile, newFilePointer, stringFile, stringFilePointer
newFile = 'Replaced.' + filename
newFilePointer = codecs.open(newFile, 'wb', 'utf-8')
stringFile = 'Localizable.strings'
stringFilePointer = codecs.open(stringFile, 'a+', 'utf-8')
file = os.path.join(dirpath,fileName)
fp = codecs.open(file, 'rb', 'utf-8')
for line in fp:
processLine(line)
fp.close()
stringFilePointer.close()
newFilePointer.close()
oldFile = os.path.join(dirpath, 'Old.' + filename)
os.system('mv ' + file + ' ' + oldFile)
os.system('mv ' + newFile + ' ' + file)
os.system('rm -f ' + oldFile)
def isIgnore(path):
igoreArr = ['Pods']
for ignoreStr in igoreArr:
if ignoreStr in path:
return True
return False
if __name__ == "__main__":
if len(sys.argv) > 1:
output = sys.argv[1]
for dirpath, dirnames, filenames in os.walk(output):
for fileName in filenames:
if isIgnore(fileName) or isIgnore(dirpath):
continue
file = os.path.join(dirpath,fileName)
if fileName.endswith('.h') or fileName.endswith('.m'):
if os.path.exists(file):
try:
print('Processing File :' + file)
processFile(dirpath, fileName)
except Exception as e:
print(e)
附上代码运行方法:
1.新建一个叫chinese_string_sort.py的文件把上诉代码复制进去并保存。
2.打开终端cd到chinese_string_sort.py文件所在位置。
3.输入python chinese_string_sort.py ~/Desktop/project(~/Desktop/project为工程所在路径,请自行修改)
4.回车,然后等待运行完毕。运行完毕后可在chinese_string_sort.py文件所在的路径里找到提取出来的Localizable.strings文件。