You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C#中如何实现String.Normalize(FormD)的反向韩文字符组合功能

韩文兼容字母组合为完整音节的实现方案

问题根因

你调用无参Normalize()默认使用NormalizationForm.FormC归一化格式,无法完成组合的核心原因是:

  • 你输入的ㄱㅗㅇㅑㅇㅇㅣ属于韩文兼容字母(Hangul Compatibility Jamo,码位范围U+3130~U+318F),这类字符是为了兼容古旧编码设计的,Unicode标准没有定义它们的组合映射规则
  • 你用NormalizationForm.FormD分解고양이得到的是标准Hangul Jamo字符,分属初声(辅音开头)、中音(元音)、终声(辅音收尾)三个独立分区,和你手动输入的兼容Jamo不是同一套码位

实现方案

需要分两步完成转换:

  1. 建立兼容Jamo到标准Jamo的映射表,把输入的兼容字符转换为可组合的标准Jamo序列
  2. 对标准Jamo序列调用Normalize(NormalizationForm.FormC)即可自动组合为完整韩文音节

C# 实现代码

using System;
using System.Collections.Generic;
using System.Text;

public static class HangulCombiner
{
    // 兼容Jamo转标准初声映射
    private static readonly Dictionary<char, char> CompatToStandardChoseong = new()
    {
        {'ㄱ', '\u1100'}, {'ㄲ', '\u1101'}, {'ㄴ', '\u1102'}, {'ㄷ', '\u1103'},
        {'ㄸ', '\u1104'}, {'ㄹ', '\u1105'}, {'ㅁ', '\u1106'}, {'ㅂ', '\u1107'},
        {'ㅃ', '\u1108'}, {'ㅅ', '\u1109'}, {'ㅆ', '\u110A'}, {'ㅇ', '\u110B'},
        {'ㅈ', '\u110C'}, {'ㅉ', '\u110D'}, {'ㅊ', '\u110E'}, {'ㅋ', '\u110F'},
        {'ㅌ', '\u1110'}, {'ㅍ', '\u1111'}, {'ㅎ', '\u1112'}
    };
    // 兼容Jamo转标准中音映射
    private static readonly Dictionary<char, char> CompatToStandardJungseong = new()
    {
        {'ㅏ', '\u1161'}, {'ㅐ', '\u1162'}, {'ㅑ', '\u1163'}, {'ㅒ', '\u1164'},
        {'ㅓ', '\u1165'}, {'ㅔ', '\u1166'}, {'ㅕ', '\u1167'}, {'ㅖ', '\u1168'},
        {'ㅗ', '\u1169'}, {'ㅘ', '\u116A'}, {'ㅙ', '\u116B'}, {'ㅚ', '\u116C'},
        {'ㅛ', '\u116D'}, {'ㅜ', '\u116E'}, {'ㅝ', '\u116F'}, {'ㅞ', '\u1170'},
        {'ㅟ', '\u1171'}, {'ㅠ', '\u1172'}, {'ㅡ', '\u1173'}, {'ㅢ', '\u1174'},
        {'ㅣ', '\u1175'}
    };
    // 兼容Jamo转标准终声映射
    private static readonly Dictionary<char, char> CompatToStandardJongseong = new()
    {
        {'ㄱ', '\u11A8'}, {'ㄲ', '\u11A9'}, {'ㄳ', '\u11AA'}, {'ㄴ', '\u11AB'},
        {'ㄵ', '\u11AC'}, {'ㄶ', '\u11AD'}, {'ㄷ', '\u11AE'}, {'ㄹ', '\u11AF'},
        {'ㄺ', '\u11B0'}, {'ㄻ', '\u11B1'}, {'ㄼ', '\u11B2'}, {'ㄽ', '\u11B3'},
        {'ㄾ', '\u11B4'}, {'ㄿ', '\u11B5'}, {'ㅀ', '\u11B6'}, {'ㅁ', '\u11B7'},
        {'ㅂ', '\u11B8'}, {'ㅄ', '\u11B9'}, {'ㅅ', '\u11BA'}, {'ㅆ', '\u11BB'},
        {'ㅇ', '\u11BC'}, {'ㅈ', '\u11BD'}, {'ㅊ', '\u11BE'}, {'ㅋ', '\u11BF'},
        {'ㅌ', '\u11C0'}, {'ㅍ', '\u11C1'}, {'ㅎ', '\u11C2'}
    };

    public static string CombineCompatJamo(string compatJamoText)
    {
        StringBuilder standardJamoBuilder = new StringBuilder();
        int position = 0;
        while (position < compatJamoText.Length)
        {
            // 匹配音节开头的初声
            if (CompatToStandardChoseong.TryGetValue(compatJamoText[position], out char choseong))
            {
                standardJamoBuilder.Append(choseong);
                position++;
                // 匹配后续的中音
                if (position < compatJamoText.Length && CompatToStandardJungseong.TryGetValue(compatJamoText[position], out char jungseong))
                {
                    standardJamoBuilder.Append(jungseong);
                    position++;
                    // 匹配可选的终声,需判断是否为下一个音节的初声
                    if (position < compatJamoText.Length && CompatToStandardJongseong.TryGetValue(compatJamoText[position], out char jongseong))
                    {
                        bool isJongseong = true;
                        if (position + 1 < compatJamoText.Length)
                        {
                            if (CompatToStandardJungseong.ContainsKey(compatJamoText[position + 1]))
                            {
                                isJongseong = false;
                            }
                        }
                        if (isJongseong)
                        {
                            standardJamoBuilder.Append(jongseong);
                            position++;
                        }
                    }
                }
            }
            else
            {
                // 非韩文字符直接保留
                standardJamoBuilder.Append(compatJamoText[position]);
                position++;
            }
        }
        // 标准Jamo序列归一化后即可得到组合后的完整音节
        return standardJamoBuilder.ToString().Normalize(NormalizationForm.FormC);
    }
}

// 测试调用
public static void Test()
{
    string input = "ㄱㅗㅇㅑㅇㅇㅣ";
    string result = HangulCombiner.CombineCompatJamo(input);
    Console.WriteLine(result); // 输出:고양이
}

上述映射表覆盖了常用韩文字母,如需处理生僻组合,补充对应映射关系即可。

内容的提问来源于stack exchange,提问作者Damn Vegetables

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.29 11:45:05