【问题标题】:Check if a string is half width or full width in C#在 C# 中检查字符串是半角还是全角
【发布时间】:2019-11-30 05:41:24
【问题描述】:

C# application on Japanese Windows OS - Present Latin as Full-Width characters

我在上面的链接中引用了接受的答案,并使用下面的代码将日语字符串从全角转换为半角,但它返回相同的全角字符串而不进行转换。

string userInput = "チヨチヨチチヨチヨチ";
string result = userInput.Normalize(NormalizationForm.FormKC);

半宽度的预期输出:チヨチヨチチヨチヨチ 实际输出:チヨチヨチチヨチヨチ(全幅)

但是,即使上面的代码应该将全角字符串转换为半角,当我将半角字符串 (チヨチヨチチヨチヨチ) 传递给上述代码时,它会将其转换为全角形式 (チヨチヨチチヨチヨチ)。

我在这里做错了什么?

无论如何,如果我的字符串已经是半角,我不希望执行上面的代码。

如何检查字符串是半角还是全角?

【问题讨论】:

  • 你能解释一下“全宽和半宽”是什么意思吗?
  • @MostafaTHIS ​​​​​​​​​​​​​​​​​​
  • 半角是这样的 1 、2、3、4、5 ...a、b、c (半角需要1个字节)。如果我们将半角改为全角 1 、2、3、4、5 ...a、b、c → 1、2、3、4、5...a、b、c (全角成本2 个字节)
  • 感谢@John 和增值税。我在以下位置找到了更多信息:en.wikipedia.org/wiki/Halfwidth_and_fullwidth_forms
  • 我测试了你的代码,它没有将半角转换为全角。我使用 .net framework 4.0 和 .net core 进行了测试。你能分享一个显示问题的代码吗?

标签: c# asp.net asp.net-core string-conversion string-operations


【解决方案1】:

根据this 文档, normalize 方法按预期工作。它必须将字符转换为标准字符,才能正确应用二进制比较。

但如果您想要一个始终将全角转换为半角的自定义转换,您可以创建一个Dictionary 来将全角字符映射到半角字符。 This link 可能有助于创建此地图。

如果你想确定字符串是半角的,那么如果它包含任何全角字符,它就会被拒绝。创建一个所有全角字符(拉丁文和日文)的字符串,然后在全角字符串中找到要测试的字符串的所有字符。

我为此目的编写了isHalfWidthString 方法,并添加了全角到半角转换器的方法。我认为这可能会有所帮助:

    public class FullWidthCharactersHandler
    {
        static Dictionary<char, char> fullWidth2halfWidthDic;
        static FullWidthCharactersHandler()
        {
            fullWidth2halfWidthDic = new Dictionary<char, char>();
            string fullWidthChars = "アイウエオカキクケコサシスセソタチツテトナニヌネノハヒフヘホマミムメモヤユヨラリルレロワヲンッァィゥェォャュョ゙゚ー0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
            string halfWidthChars = "アイウエオカキクケコサシスセソタチツテトナニヌネノハヒフヘホマミムメモヤユヨラリルレロワヲンッァィゥェォャュョ゙゚ー0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
            for (int i = 0; i < fullWidthChars.Length; i++)
            {
                fullWidth2halfWidthDic.Add(fullWidthChars[i], halfWidthChars[i]);
            }
        }

        public static bool isHalfWidthString(string toTestString)
        {
            bool isHalfWidth = true;
            foreach (char ch in toTestString)
            {
                if (fullWidth2halfWidthDic.ContainsKey(ch))
                {
                    isHalfWidth = false;
                    break;
                }
            }
            return isHalfWidth;
        }

        public static string convertFullWidthToHalfWidth(string theString)
        {
            StringBuilder sbResult = new StringBuilder(theString);
            for (int i = 0; i < theString.Length; i++)
            {
                if (fullWidth2halfWidthDic.ContainsKey(theString[i]))
                {
                    sbResult[i] = fullWidth2halfWidthDic[theString[i]];
                }
            }
            return sbResult.ToString();
        }
    }

供测试使用this link

我更新了代码以使用 Dictionary 以获得更好的性能。

【讨论】:

  • 我正在尝试使用日文字符。我已使用示例输入更新了问题。
  • 为此目的使用字符串是个坏主意。请改用std::setstd::unordered_set
  • @MostafaVatanpour 在 C# 中你仍然有 HashSet、SortedSet 和许多其他
  • @phuclv 是的,你是对的,使用哈希表是一个更好的主意并且具有更好的性能,但它需要更多的代码行。我更改了代码。谢谢。
  • @everyone 批准了这个答案,因为这是将半角假名转换为全角假名的唯一解决方案(使用字典),反之亦然。我使用 Dictionary 实现,因为一些全角假名字符的半角形式包含 Dakuten ( ゙ ) 和 Handakuten ( ゚ ) 是 2 个字符。例如全角ヷ半角ヷ
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-11-13
  • 1970-01-01
相关资源
最近更新 更多