This commit is contained in:
kawagiri 2026-05-17 22:22:15 +08:00
commit f392c3f4cb
3 changed files with 36 additions and 21 deletions

View File

@ -470,7 +470,7 @@ ExcelExportToAsset()
```
对齐规则:
1. **带前缀 `![n]`** — 按 n 值匹配中文对应的 `**<[n]id>**`
1. **带前缀 `![n]`** — 按 n 值匹配中文对应的 `**<![n]id>**`
2. **无前缀** — 按出现顺序依次对齐
#### 运行时解析

View File

@ -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 = $"**<![{prefix}]{strId}>**";
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 = $"**<![{prefix}]{subId}>**";
}
else
{

View File

@ -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 $"**<![{prefixGroup.Value}]{str}>**";
}
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 $"**<![{prefixGroup.Value}]{str}>**";
}
return m.Value;
}
// 检测嵌套:内部字符串不应再包含 **<...>**
if (Regex.IsMatch(str, @"\*\*<.+?>\*\*"))
@ -329,7 +336,7 @@ namespace Logic.Multilingual
if (prefixGroup.Success)
{
return $"**<[{prefixGroup.Value}]{id}>**";
return $"**<![{prefixGroup.Value}]{id}>**";
}
else
{
@ -342,8 +349,8 @@ namespace Logic.Multilingual
/// <summary>
/// 将其他语言的嵌入字符串对齐到中文已转换好的ID格式
/// zhResolved: 中文已经通过 UnResolveEmbeddedStrings 转换后的字符串(包含 **<id>** 和 **<[n]id>**
/// otherOrigin: 其他语言的原始字符串(包含 **<str>** 和 **<[n]str>**
/// zhResolved: 中文已经通过 UnResolveEmbeddedStrings 转换后的字符串(包含 **<id>** 和 **<![n]id>**
/// otherOrigin: 其他语言的原始字符串(包含 **<str>** 和 **<![n]str>**
/// type: 当前语言类型(用于日志)
/// itemId: 当前item的ID用于日志
/// </summary>
@ -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<string, string>(); // n -> **<[n]id>**
var zhPrefixDict = new Dictionary<string, string>(); // n -> **<![n]id>**
var zhNoPrefixList = new List<string>(); // **<id>** 有序列表
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] = $"**<![{prefixGroup.Value}]{idStr}>**"; // n -> **<![n]id>**
}
else
{
@ -378,7 +385,7 @@ namespace Logic.Multilingual
// 解析其他语言的嵌入引用
// 允许匹配 **<>**(空内容),导回时也按中文顺序对齐为 **<id>**
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]str>** 的情况使用中文对应n的 **<![n]id>**
foreach (var m in otherPrefixMatches)
{
var n = m.Groups[1].Value;