C#中文字数相关

2020-02-27  本文已影响0人  灰的狼

C#里面中文相关的测试

using System.Collections;
using System.Collections.Generic;
using System.Globalization;
using NUnit.Framework;
using UnityEngine;
using UnityEngine.TestTools;

namespace Tests
{
    public class HanTest
    {

        public static void LogCharInfo(string str)
        {
            foreach (var ch in str)
            {
                var cate = char.GetUnicodeCategory(ch);
                Debug.Log($"[{ch}]--{cate}------");
                Debug.Log($"IsControl={char.IsControl(ch)}\tIsDigit={char.IsDigit(ch)}\tIsHighSurrogate={char.IsHighSurrogate(ch)}\tIsLetter={char.IsLetter(ch)}");
                Debug.Log($"IsLetterOrDigit={char.IsLetterOrDigit(ch)}\tIsLower={char.IsLower(ch)}\tIsLowSurrogate={char.IsLowSurrogate(ch)}\tIsNumber={char.IsNumber(ch)}");
                Debug.Log($"IsPunctuation={char.IsPunctuation(ch)}\tIsSeparator={char.IsSeparator(ch)}\tIsSurrogate={char.IsSurrogate(ch)}");
                Debug.Log($"IsSymbol={char.IsSymbol(ch)}\tIsUpper={char.IsUpper(ch)}\tIsWhiteSpace={char.IsWhiteSpace(ch)}");
                Debug.Log("==============");
            }
        }

        public static void LogSubstringByTextElements(string s)
        {
            Debug.Log("----------LogSubstringByTextElements------------");
            StringInfo strInfo = new StringInfo(s);
            for (int i = 0; i < strInfo.LengthInTextElements; i++)
            {
                Debug.Log($"第[{i}]个字(文本元素)是[{strInfo.SubstringByTextElements(i, 1)}]");
            }
        }

        public static void LogElements(string s)
        {
            Debug.Log("-----------------LogElements--------------------");
            TextElementEnumerator textElementEnumerator = StringInfo.GetTextElementEnumerator(s);
            while (textElementEnumerator.MoveNext())
            {
                Debug.Log($"文本元素[{textElementEnumerator.GetTextElement()}]的起始index是[{textElementEnumerator.ElementIndex}]");
            }
        }

        public static void LogElementsStartIndex(string s)
        {
            Debug.Log("-----------LogElementsStartIndex--------------------");
            int[] indexArray = StringInfo.ParseCombiningCharacters(s);
            for (int i = 0; i < indexArray.Length; i++)
            {
                Debug.Log($"第[{i}]个元素,起始index是[{indexArray[i]}]");
            }
        }

        public static void DoTest(string s)
        {
            Debug.Log("-----DoTest----");
            Debug.Log(s);
            Debug.Log("=====================");
            LogCharInfo(s);
            LogSubstringByTextElements(s);
            LogElements(s);
            LogElementsStartIndex(s);
        }

        [Test]
        public void TestHan()
        {
            string msg = @" 哈喽,大家好,这次的分享是关于《守望先锋》(译注:下文统一简称为Overwatch)游戏架构设计和网络部分。老规矩,手机调成静音;离开时记得填写调查问卷;换下半藏,赶紧推车!(众笑)
          我是Tim Ford,是暴雪公司Overwatch开发团队老大。自从2013年夏季项目启动以来就在这个团队了。在那之前,我在《Titan》项目组,不过这次分享跟Titan没有半毛钱关系。(众笑)
          这次分享的一些技术,是用来降低不停增长的代码库的复杂度(译注,代码复杂度的概念需要读者自行查阅)。为了达到这个目的我们遵循了一套严谨的架构。最后会通过讨论网络同步(netcode)这个本质很复杂的问题,来说明具体如何管理复杂性。
 
          Overwatch是一个近未来世界观的在线团队英雄射击游戏,它的主要是特点是英雄的多样性, 每个英雄都有自己的独门绝技。";
            DoTest(msg);
        }

        [Test]
        public void TestUnicode()
        {
            string msg = "a666\u0304\u0308bc\u0327";
            DoTest(msg);
        }

        [Test]
        public void TestEn()
        {
            string msg = "hello world ! this is 666 !!!";
            DoTest(msg);
        }
    }
}

部分测试结果:

image.png
image.png
  1. 中文通常都是OtherLetter.
  2. 中文文本元素的长度直接是String的长度,也就是说一个Char就是一个汉字。
    下面是举例其他某些语言会导致文字长度不一致的情况:


    image.png
    image.png

那么怎么统计一段文字中的汉字数量?
方法一、判断IsLetter为true且是OtherLetter;这个方法比较粗糙,但也可以在只有中文英文的情况下使用;
方法二、取出每个IsLetter为true的Unicode值,并且找到汉字的Unicode范围,在这个范围内才认为是一个汉字;这个方法相对精确一些。

上一篇下一篇

猜你喜欢

热点阅读