最近在做spring boot的国际化,将后端的自定义异常抛出的提示全替换为i18n的key,一个一个手动替换很麻烦,写了两个python脚本, 一个是提取中文内容到txt中,一个是将properties中的文件替换到java代码中,虽然并不是全自动,但还是相对减轻了一些工作量。 不是很擅长写python,还原大佬指正改进。
提取
代码
import re
import os
def extract_exception_messages(java_file):
"""
从Java文件中提取异常抛出中的中文内容,写入文件
"""
unique_exception_messages = set()
with open(java_file, 'r', encoding='utf-8') as file:
for line in file:
# 对于异常全是中文的提取,如 new SystemException("查询失败,请检查输入")
direct_match = re.search(r'new\s+SystemException\("(.*?)"\)', line)
if direct_match:
message = direct_match.group(1).strip()
unique_exception_messages.add(message)
else:
# 对于使用String.format的提取 如 new SystemException(String.format("错误: %s", e.getMessage()))
format_match = re.search(r'new\s+SystemException\(String\.format\("(.*?)"\s*,\s*(.*?)\)\)', line)
if format_match:
format_string = format_match.group(1).strip()
placeholders = re.findall(r'%[sd]', format_string)
message = format_string.replace('%s', '{}').replace('%d', '{}')
unique_exception_messages.add(message)
else:
# 对于使用 new SystemException("错误:" + e.getMessage())
plus_match = re.search(r'new\s+SystemException\("(.*?)"\s*\+\s*(.*?)\s*\)', line)
if plus_match:
prefix = plus_match.group(1).strip()
suffix = plus_match.group(2).strip().strip('+').strip()
message = prefix + '{}'
if suffix:
message += suffix
unique_exception_messages.add(message)
return unique_exception_messages
def extract_exceptions_from_java_folder(java_folder, output_file):
"""
遍历文件夹下的java文件,对每个文件单独提取
"""
# 存储国际化内容
unique_exception_messages = set()
for root, dirs, files in os.walk(java_folder):
for file in files:
if file.endswith('.java'):
file_path = os.path.join(root, file)
messages = extract_exception_messages(file_path)
unique_exception_messages.update(messages)
# 将结果写入文件
with open(output_file, 'a', encoding='utf-8') as txt_file:
for message in unique_exception_messages:
txt_file.write(message + '\n')
# java项目目录和输出文件
java_folder = 'E:\\dir\\project\\src\\main\\java\\com'
output_file = 'E:\\dir\\excpetion.txt'
extract_exceptions_from_java_folder(java_folder, output_file)
注意
提取对比
new SystemException("查询失败,请检查输入") => 查询失败,请检查输入
new SystemException(String.format("错误: %s, %s", e.getMessage(), name)) => 错误: {}, {}
new SystemException("错误:" + e.getMessage()) => 错误:{}
不足之处
- 对于一些自定义参数的提取没有在
{}中加入0,1,2, ...., 需要手动加入 - 有时
{}后面会带上(很好辨认,应该是第三个正则的问题,手动改比我改代码更快)
替换
代码
import re
import os
def load_message_properties(file_path):
"""
加载i18n properties文件中的内容到map中
"""
messages = {}
with open(file_path, 'r', encoding='utf-8') as file:
for line in file:
line = line.strip()
if line and not line.startswith('#'):
# 中文为key, i18n_key作为value
value, key = line.split('=')
messages[key.strip()] = value.strip()
return messages
def replace_exceptions_with_keys(file_path, messages):
"""
替换文件中的中文为i18n key
"""
with open(file_path, 'r+', encoding='utf-8') as file:
content = file.read()
for exception_match in re.finditer(r'new\s+SystemException\("(.+?)"\)', content):
exception_message = exception_match.group(1)
if exception_message in messages:
new_exception_message = messages[exception_message]
content = content.replace(f'("{exception_message}")', f'("{new_exception_message}")')
file.seek(0)
file.write(content)
file.truncate()
def process_java_files(folder_path, messages):
"""
对java文件进行遍历处理
"""
for root, dirs, files in os.walk(folder_path):
for file in files:
if file.endswith('.java'):
java_file_path = os.path.join(root, file)
replace_exceptions_with_keys(java_file_path, messages)
def main():
# 国际化文件位置
message_properties_file = 'E:\\dir\\project\\src\\main\\resources\\messages.properties'
# java项目目录
java_folder = 'E:\\dir\\project\\src\\main\\java\\com'
# 加载国际化文件
messages = load_message_properties(message_properties_file)
# 遍历文件逐个替换
process_java_files(java_folder, messages)
if __name__ == "__main__":
main()
注意
- 只会对下面类型的内容进行替换
new SystemException("查询失败,请检查输入") => new SystemException("find.error")
后记
简单做个记录,虽然不是很完美,也相对减轻了一些工作量,抛砖引玉。