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

请求实现普通字符与下划线式Unicode字符互转的转换器

请求实现普通字符与下划线式Unicode字符互转的转换器

嘿,我完全懂你的需求——在JavaFX菜单里用带下划线的Unicode字符,又不想因为用图形丢失样式,确实挺头疼的。下面给你几种主流语言的实现方案,分两种思路:一种是直接映射预定义的带下划线Unicode字符(比如你举的ḏ对应d),另一种是用组合下划线字符生成(更通用,毕竟不是所有字母都有预组合的带下划线版本)。

一、Java 实现

方案1:预定义字符映射(针对有对应预组合Unicode的字符)

这种方式适合你提到的像d→ḏ这类有现成预组合Unicode的场景,我们先做一个映射表,然后实现互转方法:

import java.util.HashMap;
import java.util.Map;

public class UnderlineCharConverter {
    // 普通字符到带下划线Unicode的映射
    private static final Map<Character, Character> charToUnderline = new HashMap<>();
    // 带下划线Unicode到普通字符的映射
    private static final Map<Character, Character> underlineToChar = new HashMap<>();

    static {
        // 添加你需要的字符映射,比如示例中的d和ḏ
        addMapping('d', '\u1E0F');
        // 可以继续添加其他字符,比如a→ḁ(\u1E01)、b→ḇ(\u1E07)等
        addMapping('a', '\u1E01');
        addMapping('b', '\u1E07');
    }

    private static void addMapping(Character normal, Character underlined) {
        charToUnderline.put(normal, underlined);
        underlineToChar.put(underlined, normal);
    }

    // 普通字符串转带下划线字符串
    public static String toUnderlined(String input) {
        StringBuilder sb = new StringBuilder();
        for (char c : input.toCharArray()) {
            sb.append(charToUnderline.getOrDefault(c, c));
        }
        return sb.toString();
    }

    // 带下划线字符串转普通字符串
    public static String toNormal(String input) {
        StringBuilder sb = new StringBuilder();
        for (char c : input.toCharArray()) {
            sb.append(underlineToChar.getOrDefault(c, c));
        }
        return sb.toString();
    }

    // 测试用例
    public static void main(String[] args) {
        String test = "dab";
        String underlined = toUnderlined(test);
        System.out.println("转下划线后:" + underlined); // 输出 ḏḁḇ
        System.out.println("转回普通字符:" + toNormal(underlined)); // 输出 dab
    }
}

在JavaFX菜单里用的话,直接调用toUnderlined()方法处理菜单文本就行,完全不会丢失样式:

MenuItem menuItem = new MenuItem(UnderlineCharConverter.toUnderlined("File"));

方案2:组合下划线字符(通用所有字母)

如果有些字母没有预组合的带下划线Unicode,我们可以用**组合下划线字符(U+0332)**放在普通字符下方来模拟,这种方式更通用:

public class UnderlineCharConverter {
    // 普通字符转带下划线(用组合字符)
    public static String toUnderlinedWithCombining(String input) {
        StringBuilder sb = new StringBuilder();
        for (char c : input.toCharArray()) {
            sb.append(c).append('\u0332');
        }
        return sb.toString();
    }

    // 组合下划线字符转回普通字符
    public static String toNormalFromCombining(String input) {
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < input.length(); i++) {
            char c = input.charAt(i);
            // 跳过组合下划线字符
            if (c != '\u0332') {
                sb.append(c);
            }
        }
        return sb.toString();
    }

    public static void main(String[] args) {
        String test = "Hello";
        String underlined = toUnderlinedWithCombining(test);
        System.out.println("转下划线后:" + underlined); // 输出 H̲e̲l̲l̲o̲
        System.out.println("转回普通字符:" + toNormalFromCombining(underlined)); // 输出 Hello
    }
}

二、JavaScript 实现

同样提供两种方案:

方案1:预定义映射

const charToUnderline = new Map([
    ['d', '\u1E0F'],
    ['a', '\u1E01'],
    ['b', '\u1E07']
]);
const underlineToChar = new Map([...charToUnderline.entries()].map(([k, v]) => [v, k]));

function toUnderlined(input) {
    return [...input].map(c => charToUnderline.get(c) || c).join('');
}

function toNormal(input) {
    return [...input].map(c => underlineToChar.get(c) || c).join('');
}

// 测试
console.log(toUnderlined('dab')); // ḏḁḇ
console.log(toNormal('ḏḁḇ')); // dab

方案2:组合下划线

function toUnderlinedWithCombining(input) {
    return [...input].map(c => c + '\u0332').join('');
}

function toNormalFromCombining(input) {
    return [...input].filter(c => c !== '\u0332').join('');
}

// 测试
console.log(toUnderlinedWithCombining('Hello')); // H̲e̲l̲l̲o̲
console.log(toNormalFromCombining('H̲e̲l̲l̲o̲')); // Hello

三、C# 实现

方案1:预定义映射

using System;
using System.Collections.Generic;

public class UnderlineCharConverter
{
    private static readonly Dictionary<char, char> charToUnderline = new Dictionary<char, char>
    {
        {'d', '\u1E0F'},
        {'a', '\u1E01'},
        {'b', '\u1E07'}
    };

    private static readonly Dictionary<char, char> underlineToChar = new Dictionary<char, char>();

    static UnderlineCharConverter()
    {
        foreach (var pair in charToUnderline)
        {
            underlineToChar.Add(pair.Value, pair.Key);
        }
    }

    public static string ToUnderlined(string input)
    {
        char[] result = new char[input.Length];
        for (int i = 0; i < input.Length; i++)
        {
            result[i] = charToUnderline.TryGetValue(input[i], out char underlined) ? underlined : input[i];
        }
        return new string(result);
    }

    public static string ToNormal(string input)
    {
        char[] result = new char[input.Length];
        for (int i = 0; i < input.Length; i++)
        {
            result[i] = underlineToChar.TryGetValue(input[i], out char normal) ? normal : input[i];
        }
        return new string(result);
    }

    static void Main()
    {
        string test = "dab";
        string underlined = ToUnderlined(test);
        Console.WriteLine($"转下划线后:{underlined}"); // ḏḁḇ
        Console.WriteLine($"转回普通字符:{ToNormal(underlined)}"); // dab
    }
}

方案2:组合下划线

public class UnderlineCharConverter
{
    public static string ToUnderlinedWithCombining(string input)
    {
        char[] result = new char[input.Length * 2];
        int index = 0;
        foreach (char c in input)
        {
            result[index++] = c;
            result[index++] = '\u0332';
        }
        return new string(result);
    }

    public static string ToNormalFromCombining(string input)
    {
        char[] result = new char[input.Length / 2];
        int index = 0;
        for (int i = 0; i < input.Length; i += 2)
        {
            result[index++] = input[i];
        }
        return new string(result);
    }

    static void Main()
    {
        string test = "Hello";
        string underlined = ToUnderlinedWithCombining(test);
        Console.WriteLine($"转下划线后:{underlined}"); // H̲e̲l̲l̲o̲
        Console.WriteLine($"转回普通字符:{ToNormalFromCombining(underlined)}"); // Hello
    }
}

备注:内容来源于stack exchange,提问作者Dan Howard

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.23 11:22:45