20091209_english

本文探讨了inbehalfof与onbehalfof这两个短语的传统用法区别。inbehalfof通常表示为了某人的利益而行动,例如为地震灾民募捐;而onbehalfof则意味着作为某人的代理人或代表行动,比如监护人代表未成年孩子签署合同。尽管两者意义相近,但使用场景有所不同。

on behalf of

in behalf of

Traditionally,in behalf of  and on behalf of  have distinct senses. In behalf of  means “for the benefit of,” as inWe raised money in behalf of the earthquake victims. On behalf of means “as the agent of; on the part of,” as inThe guardian signed the contract on behalf of the minor child.   The two senses are quite close, however,and are often confused, even by reputable writers.

import json import os from android import XmlHandler from common import Config, TextHandler, FormatSpecifierParser from ios.StringsFileAnalysis import StringsFileAnalysis def get_android_key(val): for key, value in Config.ANDROID_LOCALE_DICT.items(): if value==val: return key return(val) def get_ios_key(val): for key, value in Config.IOS_LOCALE_DICT.items(): if value==val: return key return(val) def get_flutter_key(val): for key, value in Config.FLUTTER_LOCALE_DICT.items(): if value==val: return key return(val) def __adjust_word_in_android(word) -> str: word = str(word) replace_dictionary = {'–': '-', ' ': ' ', '…': '...', '&': '&', '–': '-', '…': '...','%': '%'} for key in replace_dictionary.keys(): word = word.replace(key, replace_dictionary[key]) text = str(word).strip() return text def _modify_item_in_strings_file(dst_strings_element_dict: dict, dst_strings_path: str): f = open(dst_strings_path, 'rb') file_list = f.readlines() f.close() file_list_update = False for element in dst_strings_element_dict: modified_strings_content = element.get_element_string_with_key_and_value(element.key, '\"' + TextHandler.deal_all_in_translate_result( dst_strings_element_dict[element]) + '\"') index = 0 found = False for line in file_list: if line.decode(encoding='utf-8').find(element.key) == 0: found = True break index = index + 1 if found: file_list_update = True file_list[index] = bytes(modified_strings_content, 'utf-8') if file_list_update: f = open(dst_strings_path, 'wb') f.writelines(file_list) f.close() def _check_english_translate(english: str, result: str): # 检查回车符和换行符 for s in ['\\r', '\\n']: if not english.count(s) == result.count(s): log_output = "回车符或者换行符不一致: " + s + " english: " + english + " result: " + result + "\r\n" print(log_output) return 0 # 检查格式占位符 for s in ['%@', '%s', '%f', '%d']: if not english.count(s) == result.count(s): log_output = "格式占位符不一致: " + s + " english: " + english + " result: " + result + "\r\n" print(log_output) return 1 # 检查翻译中是否有换行 if '\n' in result: log_output = "翻译中有换行:" + " english: " + english + " result: " + result + "\r\n" print(log_output) return 2 # 检查缩略词大小写 for s in Config.ABBR_CHECK_DICT.keys(): if result.lower().count(s) > 0: if not Config.ABBR_CHECK_DICT.get(s) in result: log_output = "缩略词错误 : " + s + " english:" + english + " result: " + result + "\r\n" print(log_output) return 3 return -1 if __name__ == "__main__": extract_root_path = os.path.join(Config.WORKSPACE_BASE_PATH + r'\Deco_APP_Sprint_All') android_extract_root = os.path.join(extract_root_path, 'Android') android_extract_root_path = os.path.join(android_extract_root, 'values-old') android_extract_root_path_new = os.path.join(android_extract_root, 'values-new') ios_extract_root_path = os.path.join(extract_root_path, 'iOS') android_old_xml_file = os.path.join(android_extract_root_path, 'values', 'strings.xml') android_new_english_list = XmlHandler.parse_xml_to_kv_list(android_old_xml_file) new_english = [englist[1] for englist in android_new_english_list] pc_extract_root_path = os.path.join(extract_root_path, 'PC') pc_old_extract_root_path = os.path.join(pc_extract_root_path, 'old') pc_new_extract_root_path = os.path.join(pc_extract_root_path, 'new') pc_english_path = os.path.join(pc_old_extract_root_path, 'en.json') flutter_extract_root_path = os.path.join(extract_root_path, 'Flutter') flutter_old_extract_root_path = os.path.join(flutter_extract_root_path, 'old') flutter_new_extract_root_path = os.path.join(flutter_extract_root_path, 'new') flutter_english_path = os.path.join(flutter_old_extract_root_path, 'intl_en.arb') android_new_english_dict = XmlHandler.parse_xml_to_kv_dict(android_old_xml_file) android_translate_dir = os.listdir(android_extract_root_path) all_english_translate_dict = dict() # locale_json_dst_file = os.path.join(os.path.join(extract_root_path), 'android_englist_translate_dict.text') # with open(locale_json_dst_file, 'r', encoding='utf-8') as f: # all_english_translate_dict = json.load(f) # ----------------- # 提取Android里有重复英文的文案 tmp_english_dict = dict() for key in android_new_english_dict.keys(): android_new_english_list = list(android_new_english_dict.values()) if android_new_english_list.count(android_new_english_dict[key]) > 1: tmp_english_dict[android_new_english_dict[key]] = android_new_english_list.count(android_new_english_dict[key]) locale_json_dst_file = os.path.join(os.path.join(extract_root_path), 'differ_english_dict.text') with open(locale_json_dst_file, 'w', encoding='utf8') as f2: json.dump(tmp_english_dict, f2, ensure_ascii=False, indent=2) # ----------------- ## 提取Android文案和iOS共有文案 # for key in android_new_english_dict.keys(): # for values_dir in android_translate_dir: # translate_xml_file = os.path.join(android_extract_root_path, values_dir, 'strings.xml') # translate_dict = XmlHandler.parse_xml_to_kv_dict(translate_xml_file) # for translate_key in translate_dict.keys(): # if key == translate_key: # all_english_key = __adjust_word_in_android(FormatSpecifierParser.replace_java_format_char(android_new_english_dict[key].replace('100%', '100%'))) # new_language_key = get_android_key(values_dir.replace('values-', '')) # translate_value = __adjust_word_in_android(FormatSpecifierParser.replace_java_format_char(translate_dict[translate_key].replace('100%', '100%'))) # if all_english_key in all_english_translate_dict.keys(): # if new_language_key in all_english_translate_dict[all_english_key].keys(): # if translate_value not in all_english_translate_dict[all_english_key][new_language_key]: # tmp_translate_list = list() # tmp_translate_list.append(all_english_translate_dict[all_english_key][new_language_key]) # tmp_translate_list.append(translate_value) # all_english_translate_dict[all_english_key][new_language_key] = tmp_translate_list # print(values_dir, new_language_key, all_english_key, translate_value, all_english_translate_dict[all_english_key][new_language_key]) # else: # print(values_dir, all_english_key, new_language_key, translate_value) # all_english_translate_dict[all_english_key][new_language_key] = translate_value # else: # tmp_translate_dict = dict() # print(values_dir, all_english_key, new_language_key, translate_value) # tmp_translate_dict[new_language_key] = translate_value # all_english_translate_dict[all_english_key] = tmp_translate_dict # break # # 读写Android翻译字典 # locale_json_dst_file = os.path.join(os.path.join(extract_root_path), 'android_englist_translate_dict.text') # with open(locale_json_dst_file, 'w', encoding='utf8') as f2: # json.dump(all_english_translate_dict, f2, ensure_ascii=False, indent=2) ## ----------------- # with open(locale_json_dst_file, 'r', encoding='utf-8') as f: # all_english_translate_dict = json.load(f) # ## ----------------- # # 读取iOS英文文案 ios_old_xml_dir = os.path.join(extract_root_path, 'en.lproj') ios_have_translation_english_dict = dict() ios_have_translation_strings_list = os.listdir(ios_old_xml_dir) for file_name in ios_have_translation_strings_list: if file_name in Config.IOS_IGNORE_COMPARE_STRINGS_NAME_LIST: continue en_strings_path = os.path.join(ios_old_xml_dir, file_name) en_strings_analysis = StringsFileAnalysis(en_strings_path) en_strings_analysis.analyze() en_strings_content_dict = en_strings_analysis.analyze_dictionary_result for key in en_strings_content_dict: value = en_strings_content_dict[key].value.strip() key = TextHandler.remove_double_quotation_marks_in_head_tail(key.strip()) value = TextHandler.deal_all_in_translate_result( (TextHandler.remove_double_quotation_marks_in_head_tail(value))) ios_have_translation_english_dict[key] = value # # 提取iOS独有文案 # ios_language_dir = os.listdir(ios_extract_root_path) # for ios_english_key in ios_have_translation_english_dict.keys(): # ios_english_value = ios_have_translation_english_dict[ios_english_key] # if ios_english_value not in all_english_translate_dict.keys(): # for ios_language_path in ios_language_dir: # ios_src_english_path = os.path.join(ios_extract_root_path, ios_language_path) # strings_file_array = os.listdir(ios_src_english_path) # for strings_file in strings_file_array: # en_strings_path = os.path.join(ios_src_english_path, strings_file) # print(en_strings_path) # en_strings_analysis = StringsFileAnalysis(en_strings_path) # en_strings_analysis.analyze() # en_strings_content_dict = en_strings_analysis.analyze_dictionary_result # for ios_translate_key in en_strings_content_dict.keys(): # new_language_key = get_ios_key(ios_language_path.replace('.lproj', '')) # value = en_strings_content_dict[ios_translate_key].value.strip() # key = TextHandler.remove_double_quotation_marks_in_head_tail(ios_translate_key.strip()) # value = TextHandler.deal_all_in_translate_result( # (TextHandler.remove_double_quotation_marks_in_head_tail(value))) # if ios_english_key == key: # if ios_english_value in all_english_translate_dict.keys(): # if new_language_key in all_english_translate_dict[ios_english_value].keys(): # if value not in all_english_translate_dict[ios_english_value][new_language_key]: # tmp_translate_list = list() # tmp_translate_list.append(all_english_translate_dict[ios_english_value][new_language_key]) # tmp_translate_list.append(value) # all_english_translate_dict[ios_english_value][new_language_key] = tmp_translate_list # print(new_language_key, strings_file, ios_english_key, ios_english_value, value) # else: # all_english_translate_dict[ios_english_value][new_language_key] = value # else: # tmp_translate_dict = dict() # tmp_translate_dict[new_language_key] = value # all_english_translate_dict[ios_english_value] = tmp_translate_dict # break # # locale_json_dst_file = os.path.join(os.path.join(extract_root_path), 'all_englist_translate_dict.text') # with open(locale_json_dst_file, 'w', encoding='utf8') as f2: # json.dump(all_english_translate_dict, f2, ensure_ascii=False, indent=2) ## ----------------- # 读取翻译字典 locale_json_dst_file = os.path.join(os.path.join(extract_root_path), 'all_englist_translate_dict_new.text') with open(locale_json_dst_file, 'r', encoding='utf-8') as f: all_english_translate_dict = json.load(f) # 合入iOS文案 ios_language_dir = os.listdir(ios_extract_root_path) for ios_language_path in ios_language_dir: ios_src_english_path = os.path.join(ios_extract_root_path, ios_language_path) strings_file_array = os.listdir(ios_src_english_path) new_language_key = get_ios_key(ios_language_path.replace('.lproj', '')) for strings_file in strings_file_array: if strings_file in Config.IOS_IGNORE_COMPARE_STRINGS_NAME_LIST: continue en_strings_path = os.path.join(ios_src_english_path, strings_file) en_strings_analysis = StringsFileAnalysis(en_strings_path) en_strings_analysis.analyze() en_strings_content_list = en_strings_analysis.analyze_array_result dst_strings_element_dict = dict() for strings_element in en_strings_content_list: strings_element_key = TextHandler.remove_double_quotation_marks_in_head_tail( strings_element.key.strip()) strings_element_english = TextHandler.remove_double_quotation_marks_in_head_tail( strings_element.value.strip()) dst_strings_element_dict[strings_element] = strings_element_english if strings_element_key in ios_have_translation_english_dict.keys() and strings_element_english == ios_have_translation_english_dict[strings_element_key] and strings_element_english not in Config.IOS_TRANSLATION_IGNORE_ENGLISH_LIST: if strings_element_english in all_english_translate_dict.keys() and new_language_key in all_english_translate_dict[strings_element_english].keys(): ios_translate_value = all_english_translate_dict[strings_element_english][new_language_key] if isinstance(ios_translate_value, list): print(ios_language_path, strings_file, strings_element_english, ios_translate_value) dst_strings_element_dict[strings_element] = ios_translate_value[0] else: dst_strings_element_dict[strings_element] = ios_translate_value _modify_item_in_strings_file(dst_strings_element_dict, en_strings_path) # 合入Android文案 android_dir = os.listdir(android_extract_root_path) for file_name in android_dir: if file_name == 'values': continue localization_dir_path = os.path.join(android_extract_root_path, file_name, 'strings.xml') localization_dst_path = os.path.join(android_extract_root_path_new, file_name, 'strings.xml') locale_dict = XmlHandler.parse_xml_to_kv_dict(localization_dir_path) new_locale_xml_dict = dict() none_translation_dict = dict() for english_key in android_new_english_dict: english = FormatSpecifierParser.replace_java_format_char(android_new_english_dict[english_key]) if english in all_english_translate_dict: new_language_key = get_android_key(file_name.replace('values-', '')) if new_language_key in all_english_translate_dict[english]: translation = all_english_translate_dict[english][new_language_key] if isinstance(translation, list): translation = translation[0] if translation == "": none_translation_dict[english_key] = english continue _check_english_translate(english, translation) if english != translation: if english_key not in locale_dict or locale_dict[english_key] == english: new_locale_xml_dict[english_key] = FormatSpecifierParser.build_format_char( android_new_english_dict[english_key], english, translation) # print('111 ' + locale_dict[english_key] + english, translation, android_new_english_dict[english_key], new_locale_xml_dict[english_key]) elif english_key not in all_english_translate_dict: if not english.startswith('@string/'): none_translation_dict[english_key] = english # new_locale_xml_dict[english_key] = android_new_english_dict[english_key] # print('222 ' + english_key, new_locale_xml_dict[english_key]) for english_key in locale_dict: if english_key in new_locale_xml_dict: continue new_locale_xml_dict[english_key] = locale_dict[english_key] print('333 ' + english_key + ' ' + new_locale_xml_dict[english_key]) for english_key in android_new_english_dict: if english_key not in locale_dict: continue english = android_new_english_dict[english_key] found_exist_translation_key = None for none_key in none_translation_dict: if english_key != none_key and english == none_translation_dict[none_key]: found_exist_translation_key = none_key break if found_exist_translation_key is not None: new_locale_xml_dict[found_exist_translation_key] = locale_dict[english_key] print('444 ' + english_key + ' ' + new_locale_xml_dict[english_key]) none_translation_dict.pop(found_exist_translation_key) XmlHandler.convert_to_xml(new_locale_xml_dict, localization_dst_path) # 合入PC文案 # pc_english_dict = dict() # with open(pc_english_path, 'r', encoding='utf-8') as f: # pc_english_dict = json.load(f) # pc_dir = os.listdir(pc_old_extract_root_path) # pattern = r'\{(.*?)\}' # for file_name in pc_dir: # if file_name != 'en.json': # translate_json = os.path.join(pc_old_extract_root_path, file_name) # translate_json_dict = dict() # with open(translate_json, 'r', encoding='utf-8') as f: # translate_json_dict = json.load(f) # print('\n', file_name, '\n') # for pc_english_key in pc_english_dict: # english = pc_english_dict[pc_english_key] # translation = english # if '{' in english and '}' in english: # englist_result = re.findall(pattern, english) # if len(englist_result) > 0: # count = 0 # for place_holder in englist_result: # english = str.replace(english, '{' + englist_result[count] + '}', # '{' + place_holder + '}') # # print(english) # count += 1 # if english in all_english_translate_dict: # new_language_key = get_ios_key(file_name.replace('.json', '')) # print(english, new_language_key) # if new_language_key in all_english_translate_dict[english].keys(): # translation = all_english_translate_dict[english][new_language_key] # if english == translation or (pc_english_key in translate_json_dict.keys() and translate_json_dict[pc_english_key] != english): # print(pc_english_key, english, translation) # else: # translate_json_dict[pc_english_key] = translation # locale_json_dst_file = os.path.join(pc_new_extract_root_path, file_name) # with open(locale_json_dst_file, 'w', encoding='utf8') as f2: # json.dump(translate_json_dict, f2, ensure_ascii=False, indent=2) # # 合入Flutter文案 # flutter_english_dict = dict() # with open(flutter_english_path, 'r', encoding='utf-8') as f: # flutter_english_dict = json.load(f) # flutter_dir = os.listdir(flutter_old_extract_root_path) # pattern = r'\{(.*?)\}' # for file_name in flutter_dir: # if file_name != 'intl_en.arb': # # if file_name != 'en.json': # translate_json = os.path.join(flutter_old_extract_root_path, file_name) # translate_json_dict = dict() # with open(translate_json, 'r', encoding='utf-8') as f: # translate_json_dict = json.load(f) # print('\n', file_name, '\n') # for flutter_english_key in flutter_english_dict: # english = flutter_english_dict[flutter_english_key] # translation = english # if '{' in english and '}' in english: # englist_result = re.findall(pattern, english) # if len(englist_result) > 0: # count = 0 # for place_holder in englist_result: # english = str.replace(english, '{' + englist_result[count] + '}', # '{' + place_holder + '}') # # print(english) # count += 1 # if english in all_english_translate_dict: # new_language_key = get_flutter_key(file_name.replace('.arb', '').replace('intl_', '')) # print(english, new_language_key) # if new_language_key in all_english_translate_dict[english].keys(): # translation = all_english_translate_dict[english][new_language_key] # if english == translation or flutter_english_key in translate_json_dict.keys() and translate_json_dict[flutter_english_key] != english: # print(flutter_english_key, english) # else: # translate_json_dict[flutter_english_key] = translation # # _check_english_translate(english, translation) # locale_json_dst_file = os.path.join(flutter_new_extract_root_path, file_name) # with open(locale_json_dst_file, 'w', encoding='utf8') as f2: # json.dump(translate_json_dict, f2, ensure_ascii=False, indent=2) 代码解析
10-15
<think>我们正在解析一个多平台文案处理的Python脚本。这个脚本的工作流程如下: 1. 分别提取iOS、Android、Flutter三个平台的新增英文文案。 2. 合并这三个平台的文案,并生成唯一的编号(用于截图等)。 3. 对文案进行占位符的标准化处理(将不同平台的占位符统一为一种格式)。 4. 生成两个Excel文件:一个是标准文案(合并后去重),另一个是参考文案(原始文案到标准文案的映射)。 接下来,我们将逐步解析代码,并解释关键部分。 注意:由于代码较长,我们不会逐行解释,而是按照功能模块进行说明。 </think>以下是针对多平台文案提取与处理代码的详细解析,结合跨平台开发最佳实践和引用内容进行说明: ### 一、代码功能概述 该Python脚本实现多平台国际化文案自动化管理,核心流程包括: 1. **多平台新增文案提取**:iOS/Android/Flutter平台的新增文案抽取 2. **跨平台文案合并**:识别独有/共有文案并生成唯一ID 3. **占位符标准化处理**:统一不同平台的占位符格式 4. **文案翻译管理**:对接现有翻译库避免重复翻译 5. **Excel报告生成**:输出标准文案和参考映射表 ```mermaid graph TD A[启动脚本] --> B[iOS文案提取] A --> C[Android文案提取] A --> D[Flutter文案提取] B --> E[文案合并分析] C --> E D --> E E --> F[占位符标准化] F --> G[翻译库校验] G --> H[Excel报告生成] ``` ### 二、关键技术模块解析 #### 1. 多平台文案提取 **iOS平台**: ```python ios_new_english_list = StringsExtractor(ios_pre_en_dir, ios_cur_en_dir).extract() ``` - 使用`StringsExtractor`解析`.strings`文件,通过`NSLocalizedString`宏提取本地化字符串[^1] - 比对新旧版本目录实现增量提取 **Android平台**: ```python android_new_english_list = XmlExtractor(android_old_xml_file, android_new_xml_file).extract() ``` - 基于XML解析器处理`strings.xml`资源文件 - 支持`<string>`标签嵌套和CDATA特殊格式[^3] **Flutter平台**: ```python flutter_new_english_list = JsonExtractor(flutter_old_json_file, flutter_new_json_file).extract() ``` - 解析ARB(Application Resource Bundle)格式的JSON文件 - 跳过`@`前缀的元数据字段(如`@description`) #### 2. 跨平台文案合并 ```python new_english_dict = dict() for val in ios_new_english_list: if val not in android_new_english_list: # iOS独有文案处理 elif val in android_new_english_list: # 跨平台共有文案处理 ``` - **去重机制**:建立字典结构避免重复记录 - **来源标记**:通过`platform`字段标注文案来源(iOS/Android/Flutter/跨平台) - **ID生成策略**: ```python no_generator = NoGenerator(Config.DECO_ALL_STRINGS_PATH) no_generator.get_no(val, 'iOS') # 生成唯一ID ``` 基于历史最大ID实现自增编号,确保ID全局唯一 #### 3. 占位符标准化处理 ```python if new_info.platform == 'iOS': english_format = FormatSpecifierParser.replace_ios_format_char(new_info.english) else: english_format = FormatSpecifierParser.replace_java_format_char(new_info.english) ``` - **iOS占位符**:`%@` → `{0}` (Objective-C/Swift格式) - **Android占位符**:`%s`/`%d` → `{0}` (Java格式) - **Flutter占位符**:`{variable}` → `{0}` (Dart格式) - **标准化意义**:解决跨平台占位符差异导致翻译错误[^2] #### 4. 翻译库校验 ```python with open(locale_json_dst_file, 'r') as f: all_english_translate_dict = json.load(f) if standard_info.english in all_english_translate_dict.keys(): print('已有翻译') # 跳过已翻译文案 else: standard_excel_array.append(standard_info) # 新增待翻译项 ``` - 加载历史翻译字典实现文案去重 - 仅处理未翻译的新增文案,提升运营效率 #### 5. Excel报告生成 ```python TranslateInfoExcelWriter.create_excel_with_all_info_list(standard_excel_path, standard_excel_array) ``` 输出两种报告: 1. **标准文案报告**(Sprint_All.xls) - 包含文案ID、标准化文案、平台来源、翻译备注 2. **参考映射报告**(Refer_Standard.xls) - 记录原始文案到标准化文案的映射关系 ### 三、性能优化分析 1. **数据结构优化** - 使用字典(`dict`)实现O(1)复杂度文案查重 - 排序采用`sort(key=lambda)`避免全量比较 2. **增量处理机制** ```python # 示例:iOS增量提取 StringsExtractor(ios_pre_en_dir, ios_cur_en_dir) ``` 通过新旧版本目录比对,仅处理新增/变动文案 3. **内存管理** - 流式读取大文件(XML/JSON) - 分批次写入Excel避免内存溢出 ### 四、应用扩展方向 1. **语音文案提取** 集成百度语音API可实现音频文案自动化提取[^4]: ```python from aip import AipSpeech client = AipSpeech(APP_ID, API_KEY, SECRET_KEY) result = client.asr(audio_data, 'wav', 16000, {'dev_pid':1537}) ``` 2. **多语言支持** 扩展语言配置文件即可支持多语言提取: ```python # 配置文件示例 languages = ['en', 'zh', 'ja', 'ko'] for lang in languages: extract_l10n_resources(lang) ``` 3. **文档自动化** 结合`python-docx`实现Word报告自动生成[^3]: ```python from docx import Document doc = Document() doc.add_heading('多平台文案报告', 0)
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值