Android項目資源字符串內容多語言對齊工具 Python

Android項目資源字符串內容多語言對齊工具:

#!/usr/bin/env python3import re
from dataclasses import dataclass, field
from typing import Optional, Dict, List
from pathlib import Path
import tkinter as tk
from tkinter import filedialog, messagebox@dataclass
class StringLine:name: Optional[str]raw: strtext: Optional[str] = Noneattrs: Dict[str, str] = field(default_factory=dict)def parse_string_lines(xml_path: Path) -> List[StringLine]:lines = []last_line_empty = Falsestring_tag_pattern = re.compile(r'<string\s+([^>]+)>(.*?)</string>', re.DOTALL)attr_pattern = re.compile(r'(\w+)="(.*?)"')with xml_path.open(encoding='utf-8') as f:for line in f:stripped = line.strip()if not stripped:if not last_line_empty:lines.append(StringLine(name=None, raw="\n"))last_line_empty = Truecontinuelast_line_empty = Falsematch = string_tag_pattern.match(stripped)if match:attr_text, content = match.groups()attrs = dict(attr_pattern.findall(attr_text))name = attrs.get("name")lines.append(StringLine(name=name, raw=line, text=content, attrs=attrs))else:lines.append(StringLine(name=None, raw=line))return linesdef map_string_lines(lines: List[StringLine]) -> Dict[str, StringLine]:return {line.name: line for line in lines if line.name}def align_string_lines(base_lines: List[StringLine], target_lines: List[StringLine]) -> List[StringLine]:target_map = map_string_lines(target_lines)aligned_lines = []for line in base_lines:if line.name:target_line = target_map.pop(line.name, None)aligned_lines.append(target_line if target_line else line)else:aligned_lines.append(line)if target_map:aligned_lines.append(StringLine(name=None, raw="\n"))aligned_lines.append(StringLine(name=None, raw="\n"))aligned_lines.extend(target_map.values())return aligned_linesdef write_aligned_lines(lines: List[StringLine], output_path: Path):with output_path.open('w', encoding='utf-8') as f:# f.write('<resources>\n')for line in lines:f.write(line.raw.rstrip('\n') + '\n')# f.write('</resources>\n')class AlignStringsApp:def __init__(self, root):self.root = rootself.root.title("Android 資源文件多語言字符串對齊工具-WKF")self.root.resizable(False, False)# 計算居中坐標win_width, win_height = 916, 190x = (self.root.winfo_screenwidth() - win_width) // 2y = (self.root.winfo_screenheight() - win_height) // 2self.root.geometry(f"{win_width}x{win_height}+{x}+{y}")self.base_file = Noneself.res_dir = Noneself.output_dir = Nonetk.Label(root, text="基準 strings.xml 文件:").grid(row=0, column=0, sticky="w", padx=(10, 0), pady=(16, 0))self.base_entry = tk.Entry(root, width=100, state="readonly")self.base_entry.grid(row=0, column=1, pady=(16, 0))tk.Button(root, text="選擇", width=6, command=self.select_base_file).grid(row=0, column=2, pady=(16, 0))tk.Label(root, text="res 根目錄:").grid(row=1, column=0, sticky="w", padx=(10, 0))self.res_entry = tk.Entry(root, width=100, state="readonly")self.res_entry.grid(row=1, column=1)tk.Button(root, text="選擇", width=6, command=self.select_res_dir).grid(row=1, column=2)tk.Label(root, text="輸出目錄:").grid(row=2, column=0, sticky="w", padx=(10, 0))self.out_entry = tk.Entry(root, width=100, state="readonly")self.out_entry.grid(row=2, column=1)tk.Button(root, text="選擇", width=6, command=self.select_output_dir).grid(row=2, column=2)self.align_button = tk.Button(root, text="一鍵對齊", width=16, height=2, command=self.align_strings)self.align_button.grid(row=3, column=1, pady=10)messagebox.showinfo("提示","本工具以選擇的xml文件為基準對齊內容,對齊的文件中若不存在則補充基準的內容,若多了則保留在處理后的文件末尾!")def select_base_file(self):path = filedialog.askopenfilename(filetypes=[("XML 文件", "*.xml")])if path:self.base_file = Path(path)self.base_entry.config(state="normal")self.base_entry.delete(0, tk.END)self.base_entry.insert(0, str(self.base_file))self.base_entry.config(state="readonly")def select_res_dir(self):path = filedialog.askdirectory()if path:self.res_dir = Path(path)self.res_entry.config(state="normal")self.res_entry.delete(0, tk.END)self.res_entry.insert(0, str(self.res_dir))self.res_entry.config(state="readonly")def select_output_dir(self):path = filedialog.askdirectory()if path:self.output_dir = Path(path)self.out_entry.config(state="normal")self.out_entry.delete(0, tk.END)self.out_entry.insert(0, str(self.output_dir))self.out_entry.config(state="readonly")def align_strings(self):# 判斷是否路徑都已選擇if not self.base_file or not self.base_file.exists():messagebox.showwarning("警告", "請先選擇【基準 strings.xml 文件】")returnif not self.res_dir or not self.res_dir.exists():messagebox.showwarning("警告", "請先選擇【res 根目錄】")returnif not self.output_dir or not self.output_dir.exists():messagebox.showwarning("警告", "請先選擇【輸出目錄】")returntry:base_lines = parse_string_lines(self.base_file)base_name = self.base_file.namefor xml_path in self.res_dir.rglob(base_name):target_lines = parse_string_lines(xml_path)aligned = align_string_lines(base_lines, target_lines)relative = xml_path.relative_to(self.res_dir)out_path = self.output_dir / relativeout_path.parent.mkdir(parents=True, exist_ok=True)write_aligned_lines(aligned, out_path)messagebox.showinfo("完成", "對齊完成!")except Exception as e:messagebox.showerror("錯誤", f"對齊失敗: {e}")if __name__ == "__main__":window = tk.Tk()app = AlignStringsApp(window)window.mainloop()

?工具運行截圖:

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/85508.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/85508.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/85508.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

創客匠人分享:知識變現時代的創始人 IP 打造路徑

當知識付費市場規模突破千億&#xff0c;創始人 IP 已成為知識變現的 “流量引擎”。創客匠人結合陳雷教授的實戰經驗&#xff0c;拆解創始人 IP 從 0 到 1 的打造路徑&#xff0c;為內容創業者提供從流量引流到商業變現的全鏈路思路。 一、破局認知&#xff1a;IP 打造的核心…

【數據分析五:Feature Engineering】特征工程

一、特征工程定義 在數據預處理以后&#xff08;或者數據預處理過程中&#xff09;&#xff0c;如何從數據中提取有效的特征&#xff0c;使這些特征能夠盡可能的表達原始數據中的信息&#xff0c;使得后續建立的數據模型能達到更好的效果&#xff0c;就是特征工程所要做的工作…

標桿確立!永洪科技位于IDC報告Data Analytics領域象限排頭位!

近日&#xff0c;全球知名市場研究機構IDC發布的《數據管理分析與生成式AI發展趨勢及最佳實踐》報告&#xff0c;為正處于數字化轉型深水區的企業描繪了清晰的技術演進藍圖。在這幅權威繪制的產業圖譜中&#xff0c;“Data Analytics”&#xff08;數據分析&#xff09;作為連接…

啟動tomcat控制臺日志出現亂碼

當我們啟動tomcat控制臺日志出現亂碼怎么辦&#xff1f; 解決方案&#xff1a; 在tomcat根目錄中config文件夾下將log.properties文件中將默認控制臺日志輸出編碼UTF修改成GBK或者GB2312都可以。 java.util.logging.ConsoleHandler.encoding UTF-8 修改為&#xff1a; j…

【橘子的AI | 每日一課】Day4!機器學習 (ML) 基礎

機器學習 (ML) 基礎介紹 一、機器學習的定義 從廣義上來說&#xff0c;機器學習是一種能夠賦予機器學習的能力以此讓它完成直接編程無法完成的功能的方法。但從實踐的意義上來說&#xff0c;機器學習是一種通過利用數據&#xff0c;訓練出模型&#xff0c;然后使用模型預測的…

【C語言】藥店藥品管理系統 -丨完整源碼與實現解析

系統概述 這是一個功能完善的藥店藥品管理系統&#xff0c;使用C語言開發&#xff0c;基于鏈表數據結構實現。系統提供藥品信息的增刪改查、排序和持久化存儲功能&#xff0c;適用于藥店日常藥品管理工作。 數據結構設計 #define MAX_NAME_LEN 50 #define MAX_ID_LEN 20 #de…

sass-loader與webpack版本沖突解決方案

#npm i 錯誤解決記錄# 最開始錯誤 &#xff1a;拉取代碼&#xff0c;增加依賴時&#xff0c;報錯 問題&#xff1a; 在安裝sass-loader10.1.1時&#xff0c;發現與現有的webpack版本有沖突。 當前項目已經安裝了webpack4.28.4&#xff08;通過peer dependency requirements f…

常見誤區解讀之三:超融合只適合外圍/輕量業務場景,無法承載數據庫等關鍵業務?

作者&#xff1a;SmartX 金融團隊 祝志剛 在前兩期“超融合常見誤區解讀”中&#xff0c;我們分別解讀了如何以超融合建云并進行大規模部署。而對于生產業務場景&#xff0c;部分行業用戶和業界人士可能還會有這樣的認知&#xff1a; “超融合管理簡單、成本也低&#xff0c;…

Kafka重平衡機制深度解析:原理、觸發條件與應對策略

引言 在Kafka分布式消息系統中&#xff0c;重平衡&#xff08;Rebalance&#xff09;是一個至關重要的機制&#xff0c;它確保消費者組中的各個消費者實例能夠公平地分擔主題分區的消費任務。然而&#xff0c;重平衡過程也可能帶來短暫的消費停頓和性能波動&#xff0c;處理不…

使用 Docker Compose 安裝 Milvus(單機版)

1. 創建專用目錄并進入 mkdir milvus-standalone && cd milvus-standalone 2. 下載 docker-compose.yml 文件 使用官方提供的配置文件&#xff08;以 Milvus v2.3.3 為例&#xff09;&#xff1a; wget https://github.com/milvus-io/milvus/releases/download/v2.3…

【MySQL篇05】:事務的 ACID 性(數據庫原理篇)

文章目錄 一、事務的ACID特性二、數據庫原理例題與 ACID 特性判斷三、拓展&#xff08;undolog 與 redolog&#xff09; 一、事務的ACID特性 綜述&#xff1a; 原子性&#xff08;Atomicity&#xff09;&#xff1a;事務是不可分割的最小操作單元&#xff0c;要么全部成功&…

crawl4ai 框架的入門講解和實戰指南——基于Python的智能爬蟲框架,集成AI(如NLP/OCR)實現自動化數據采集與處理

一、crawl4ai 框架簡介 1. 框架定位 核心功能&#xff1a;基于Python的智能爬蟲框架&#xff0c;集成AI&#xff08;如NLP/OCR&#xff09;實現自動化數據采集與處理 關鍵特性&#xff1a; 零配置快速啟動&#xff08;自動識別網頁結構&#xff09; 內置反反爬機制&#xff…

受夠垃圾翻譯!CodeBuddy 8 分鐘造神器,劃詞秒翻 + 自動適配所有網頁

本文所使用的 CodeBuddy 免費下載鏈接&#xff1a;騰訊云代碼助手 CodeBuddy - AI 時代的智能編程伙伴 前言 作為一個天天泡在 GitHub 上扒項目的人&#xff0c;翻譯問題簡直是我 “挖寶” 路上的頭號絆腳石&#xff01;想研究國外大神的優質開源項目&#xff0c;不是被機翻軟…

零基礎設計模式——總結與進階 - 2. 反模式

第五部分&#xff1a;總結與進階 - 2. 反模式 (Anti-Patterns) 在軟件開發中&#xff0c;我們追求良好的設計模式以構建健壯、可維護的系統。然而&#xff0c;同樣存在一些常見的、導致不良后果的解決方案&#xff0c;這些被稱為“反模式”。理解反模式&#xff0c;可以幫助我…

音視頻流媒體高級開發-學習路線

原文作者&#xff1a;Linux 原文鏈接&#xff1a;音視頻流媒體高級開發-學習路線 如果你想往音視頻方向發展&#xff0c;那么本文一定要認真閱讀~ 大家都知道音視頻開發薪資高、門檻高、發展空間大&#xff0c;心里蠢蠢欲動&#xff0c;卻不知道怎么入門&#xff0c;怎么進階…

LINUX 通過rsync同步 免密備份

1&#xff0c;增加免密碼用戶密碼 useradd backup echo "5566777" | passwd --stdin backup echo "backup ALL(ALL) ALL" >> /etc/sudoers # 源服務器操作 ssh client_usersource_server ssh-keygen -t rsa # 一路回車 ssh-copy-id serv…

在使用 HTML5 的 <video> 標簽嵌入視頻時,有時會遇到無法播放 MP4 文件的問題

原因分析&#xff1a; 只能播放聲音&#xff0c;卻無法播放視頻。這通常是由于視頻編碼格式不兼容導致的。雖然 MP4 是一種常見的視頻格式&#xff0c;但它包含多種編碼方式&#xff0c;并非所有編碼方式都受 HTML5 支持。 解決方案&#xff1a; 確認視頻編碼格式&#xff1a; …

【bugfix】記一次Spring Boot 配置層級錯誤導致數據庫連接失敗

前言&#xff1a;為什么你的數據庫配置讀不到&#xff1f; 在 Spring Boot 項目中&#xff0c;配置文件的層級&#xff08;prefix&#xff09; 是決定屬性能否被正確解析的核心因素。一個看似微小的縮進錯誤&#xff0c;可能導致整個應用的數據庫連接失敗、服務啟動異常&#…

wpf 隊列(Queue)在視覺樹迭代查找中的作用分析

文章目錄 隊列(Queue)在視覺樹迭代查找中的作用分析示例代碼一、隊列的核心作用1. 替代遞歸的迭代機制2. 實現廣度優先搜索(BFS) 二、隊列的工作流程1. 初始化階段2. 處理循環 三、隊列操作的詳細步驟查找過程分解&#xff1a; 四、為什么使用隊列而不是其他數據結構1. 與棧(St…

快手數據開發面試SQL題:取窗口內排名第一和排名倒數第一的作為兩個字段輸出

目錄 問題描述 樣例數據表 sales 解決方案 第三步:使用條件聚合將多行合并為單行輸出" 步驟1:計算排名的中間結果 中間結果輸出: 步驟2:最終查詢(處理并列情況) 最終輸出結果: 關鍵點解釋: RANK() OVER (PARTITION BY group_id ORDER BY amount DESC):…