Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Check if a string is half width or full width in C#

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

I referred the accepted answer in the above link and is using the code below to convert Japanese string from full width to half width but it is returning the same full width string without converting.

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

Expected output in half width: チヨチヨチチヨチヨチ Actual output: チヨチヨチチヨチヨチ (full width)

However, even though the above code is supposed to convert a full width string to half width, when I pass the half width string (チヨチヨチチヨチヨチ) to the above code, it converts it to full width form (チヨチヨチチヨチヨチ).

What am I doing wrong here?

Anyways I don’t want the above code to be executed if my string is already in half-width.

How can I check if a string is half width or full width?

like image 410
RP1 Avatar asked Nov 17 '22 04:11

RP1


1 Answers

According to this document, the normalize method works as expected. It must convert characters to the standard characters, so the binary comparison can be applied correctly.

But if you want a custom conversion that always converts full-width to half-width, you can create a Dictionary to map full-width to half-width characters. This link may be helpful to create this map.

If you want to be sure that the string is in half-width then if it contains any full-width character, it is rejected. Create a string of all full-width characters(Latin and Japanese) then find all characters of the to test string in the full-width characters string.

I wrote isHalfWidthString method for this purpose and added full-width to half-width converter method also. I thought it may be helpful:

    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();
        }
    }

For test use this link.

I updated the code to use Dictionary for better performance.

like image 105
Mostafa Vatanpour Avatar answered Dec 01 '22 00:12

Mostafa Vatanpour