From 8125c959290e67e58c094746b0fda99a92e5cc8e Mon Sep 17 00:00:00 2001 From: wuwenbo Date: Sun, 17 May 2026 22:08:17 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A4=9A=E8=AF=AD=E8=A8=80=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- MD/GameMDInDetail/多语言系统详解.md | 2 +- .../Editor/MultilingualEditorWindow.cs | 15 +++++-- .../Multilingual/MultilingualData.cs | 40 +++++++++++-------- 3 files changed, 36 insertions(+), 21 deletions(-) diff --git a/MD/GameMDInDetail/多语言系统详解.md b/MD/GameMDInDetail/多语言系统详解.md index 1d3c7056f..8cb935f39 100644 --- a/MD/GameMDInDetail/多语言系统详解.md +++ b/MD/GameMDInDetail/多语言系统详解.md @@ -470,7 +470,7 @@ ExcelExportToAsset() ``` 对齐规则: -1. **带前缀 `![n]`** — 按 n 值匹配中文对应的 `**<[n]id>**` +1. **带前缀 `![n]`** — 按 n 值匹配中文对应的 `****` 2. **无前缀** — 按出现顺序依次对齐 #### 运行时解析 diff --git a/Unity/Assets/Scripts/TH1_Logic/Editor/MultilingualEditorWindow.cs b/Unity/Assets/Scripts/TH1_Logic/Editor/MultilingualEditorWindow.cs index 8f35d56e8..edd9c37d3 100644 --- a/Unity/Assets/Scripts/TH1_Logic/Editor/MultilingualEditorWindow.cs +++ b/Unity/Assets/Scripts/TH1_Logic/Editor/MultilingualEditorWindow.cs @@ -1300,10 +1300,10 @@ namespace Logic.Editor continue; } - // 检查是否以 [n] 开头 + // 检查是否以 ![n] 或历史格式 [n] 开头 string prefix = null; string actualStr = innerContent; - var prefixRegex = new Regex(@"^!\[([^\]]*)\](.*)$", RegexOptions.Singleline); + var prefixRegex = new Regex(@"^!?\[([^\]]*)\](.*)$", RegexOptions.Singleline); var prefixMatch = prefixRegex.Match(innerContent); if (prefixMatch.Success) { @@ -1323,6 +1323,15 @@ namespace Logic.Editor if (uint.TryParse(actualStr, out var strId)) { _activeSet.Add(strId); + if (prefix != null) + { + var canonical = $"****"; + if (match.Value != canonical) + { + replaced = replaced.Substring(0, match.Index) + canonical + + replaced.Substring(match.Index + match.Length); + } + } continue; } if (string.IsNullOrEmpty(actualStr)) continue; @@ -1344,7 +1353,7 @@ namespace Logic.Editor string replacement; if (prefix != null) { - replacement = $"**<[{prefix}]{subId}>**"; + replacement = $"****"; } else { diff --git a/Unity/Assets/Scripts/TH1_Logic/Multilingual/MultilingualData.cs b/Unity/Assets/Scripts/TH1_Logic/Multilingual/MultilingualData.cs index b95d06fdc..5c73b7d3f 100644 --- a/Unity/Assets/Scripts/TH1_Logic/Multilingual/MultilingualData.cs +++ b/Unity/Assets/Scripts/TH1_Logic/Multilingual/MultilingualData.cs @@ -198,7 +198,7 @@ namespace Logic.Multilingual var origin = item.GetStrByType(type); if (string.IsNullOrEmpty(origin)) return result; - var regex = new Regex(@"\*\*<(?:!\[(\d+)\])?(\d+)>\*\*"); + var regex = new Regex(@"\*\*<(?:!?\[(\d+)\])?(\d+)>\*\*"); var matches = regex.Matches(origin); foreach (Match m in matches) { @@ -216,7 +216,7 @@ namespace Logic.Multilingual { if (string.IsNullOrEmpty(origin)) return string.Empty; - var regex = new Regex(@"\*\*<(?:!\[(\d+)\])?(\d+)>\*\*"); + var regex = new Regex(@"\*\*<(?:!?\[(\d+)\])?(\d+)>\*\*"); var result = regex.Replace(origin, m => { var prefixGroup = m.Groups[1]; // [n] 中的 n @@ -255,7 +255,7 @@ namespace Logic.Multilingual { if (string.IsNullOrEmpty(origin)) return string.Empty; - var regex = new Regex(@"\*\*<(?:!\[(\d+)\])?(\d+)>\*\*"); + var regex = new Regex(@"\*\*<(?:!?\[(\d+)\])?(\d+)>\*\*"); var result = regex.Replace(origin, m => { var prefixGroup = m.Groups[1]; // [n] 中的 n @@ -275,7 +275,7 @@ namespace Logic.Multilingual if (prefixGroup.Success) { - return $"**<[{prefixGroup.Value}]{str}>**"; + return $"****"; } else { @@ -291,14 +291,21 @@ namespace Logic.Multilingual { if (string.IsNullOrEmpty(origin)) return string.Empty; - var regex = new Regex(@"\*\*<(?:!\[(\d+)\])?(.+?)>\*\*"); + var regex = new Regex(@"\*\*<(?:!?\[(\d+)\])?(.+?)>\*\*"); var result = regex.Replace(origin, m => { var prefixGroup = m.Groups[1]; // [n] 中的 n var str = m.Groups[2].Value; // 内部字符串 // 已经是 id 则跳过 - if (uint.TryParse(str, out _)) return m.Value; + if (uint.TryParse(str, out _)) + { + if (prefixGroup.Success) + { + return $"****"; + } + return m.Value; + } // 检测嵌套:内部字符串不应再包含 **<...>** if (Regex.IsMatch(str, @"\*\*<.+?>\*\*")) @@ -329,7 +336,7 @@ namespace Logic.Multilingual if (prefixGroup.Success) { - return $"**<[{prefixGroup.Value}]{id}>**"; + return $"****"; } else { @@ -342,8 +349,8 @@ namespace Logic.Multilingual /// /// 将其他语言的嵌入字符串对齐到中文已转换好的ID格式 - /// zhResolved: 中文已经通过 UnResolveEmbeddedStrings 转换后的字符串(包含 **** 和 **<[n]id>**) - /// otherOrigin: 其他语言的原始字符串(包含 **** 和 **<[n]str>**) + /// zhResolved: 中文已经通过 UnResolveEmbeddedStrings 转换后的字符串(包含 **** 和 ****) + /// otherOrigin: 其他语言的原始字符串(包含 **** 和 ****) /// type: 当前语言类型(用于日志) /// itemId: 当前item的ID(用于日志) /// @@ -354,11 +361,11 @@ namespace Logic.Multilingual if (string.IsNullOrEmpty(zhResolved)) return otherOrigin; // 解析中文已转换的嵌入引用 - var zhRegex = new Regex(@"\*\*<(?:!\[(\d+)\])?(\d+)>\*\*"); + var zhRegex = new Regex(@"\*\*<(?:!?\[(\d+)\])?(\d+)>\*\*"); var zhMatches = zhRegex.Matches(zhResolved); // 构建中文的 n->完整匹配 字典(带前缀n的)和 无前缀的有序列表 - var zhPrefixDict = new Dictionary(); // n -> **<[n]id>** + var zhPrefixDict = new Dictionary(); // n -> **** var zhNoPrefixList = new List(); // **** 有序列表 foreach (Match m in zhMatches) @@ -368,7 +375,7 @@ namespace Logic.Multilingual if (prefixGroup.Success) { - zhPrefixDict[prefixGroup.Value] = m.Value; // n -> **<[n]id>** + zhPrefixDict[prefixGroup.Value] = $"****"; // n -> **** } else { @@ -378,7 +385,7 @@ namespace Logic.Multilingual // 解析其他语言的嵌入引用 // 允许匹配 **<>**(空内容),导回时也按中文顺序对齐为 **** - var otherRegex = new Regex(@"\*\*<(?:!\[(\d+)\])?(.*?)>\*\*"); + var otherRegex = new Regex(@"\*\*<(?:!?\[(\d+)\])?(.*?)>\*\*"); var otherMatches = otherRegex.Matches(otherOrigin); // 分类其他语言的匹配:带前缀n的 和 不带前缀的 @@ -390,15 +397,14 @@ namespace Logic.Multilingual var prefixGroup = m.Groups[1]; var content = m.Groups[2].Value; - // 如果内容已经是纯数字(id),跳过 - if (uint.TryParse(content, out _)) continue; - if (prefixGroup.Success) { otherPrefixMatches.Add(m); } else { + // 不带顺序前缀且内容已经是纯数字(id)时无需按顺序再次对齐 + if (uint.TryParse(content, out _)) continue; otherNoPrefixMatches.Add(m); } } @@ -407,7 +413,7 @@ namespace Logic.Multilingual // 收集所有需要替换的操作 var replacements = new List<(int index, int length, string replacement)>(); - // 1. 处理带前缀 **<[n]str>** 的情况:使用中文对应n的 **<[n]id>** + // 1. 处理带前缀 **** 的情况:使用中文对应n的 **** foreach (var m in otherPrefixMatches) { var n = m.Groups[1].Value;