将单字节字符串(半角)转换为双字节(全角)

问题描述 投票:0回答:2

最近我在 C# 应用程序中遇到了这段代码。

cDataString = Strings.StrConv(cDataString, VbStrConv.Wide);

我理解

StrConv
是VB的字符串函数。您可以通过包含“using Microsoft.VisualBasic;”来调用它。

它应该将半角日语字符转换为全角字符。

我的问题是: 有没有一种方法可以在不使用 VB 函数且不包含 VB 标头的情况下仅使用标准 C# 函数来实现相同的目的?我知道有很多 C# 字符串转换函数,其中一些可以从 unicode 转换为 ansi,反之亦然,等等。但我不确定其中任何一个是否会直接得到与上面的 VB 完全相同的结果。那么,这可以在 c# 中完成吗?

感谢您的时间和努力。

更新: 我遇到了 5 年前提出的这个问题。答案和讨论确实表明了一些可以实现的方法。我特别想知道的是,经过 5 年的新版本和其他情况,是否有一种更简单、更好的方法可以在 .NET 中实现此目的,而不依赖于 VB 函数或 VB 库?

c# string cjk string-conversion
2个回答
2
投票

C# 中没有等效函数。

如果您遵循

Microsoft.VisualBasic.dll
StrConv
的源代码,您会看到它实际上在内部 p/调用
LCMapString
,类似于您链接的 答案

如果您不想引用

Microsoft.VisualBasic.dll
,您可以将 p/invoke 包装到用 C# 编写的帮助器类或服务中,如下所示...

// NOTE: CODE NOT TESTED
// Code from John Estropia's StackOverflow answer
// https://stackoverflow.com/questions/6434377/converting-zenkaku-characters-to-hankaku-and-vice-versa-in-c-sharp

public static class StringWidthHelper
{
    private const uint LOCALE_SYSTEM_DEFAULT = 0x0800;
    private const uint LCMAP_HALFWIDTH = 0x00400000;
    private const uint LCMAP_FULLWIDTH = 0x00800000;

    public static string ToHalfWidth(string fullWidth)
    {
        StringBuilder sb = new StringBuilder(256);
        LCMapString(LOCALE_SYSTEM_DEFAULT, LCMAP_HALFWIDTH, fullWidth, -1, sb, sb.Capacity);
        return sb.ToString();
    }

    public static string ToFullWidth(string halfWidth)
    {
        StringBuilder sb = new StringBuilder(256);
        LCMapString(LOCALE_SYSTEM_DEFAULT, LCMAP_FULLWIDTH, halfWidth, -1, sb, sb.Capacity);
        return sb.ToString();
    }

    [DllImport("kernel32.dll", CharSet = CharSet.Unicode)]
    private static extern int LCMapString(uint Locale, uint dwMapFlags, string lpSrcStr, int cchSrc, StringBuilder lpDestStr, int cchDest);
}

否则,您可以构建一个字典来充当查找表。


1
投票

不是通用解决方案,但在我的特殊情况下(半角日语片假名

ラーメン
到全角片假名
ラーメン
),带有 NFKC 选项的
String#Normalize
完成了这项工作。

请注意,此方法与VB one并不完全兼容(例如,它将全角数字

42
转换为半角数字
42
),因此您需要选择字符来替换,例如:

// Half-width katakana to Full-width katakana
Regex halfKatakana = new Regex(@"[\uFF61-\uFF9F]+");
cDataString = halfKatakana.Replace(cDataString, (m) => m.Value.Normalize(NormalizationForm.FormKC));
© www.soinside.com 2019 - 2024. All rights reserved.