• c#测试字符串是否为GUID的几种方法


    以前为了赶项目遇到这种需求时,也没过多考虑性能因素,随便写了一个(现在看起来很原始的)方法来实现:

    static bool IsGuidByError(string strSrc)
            {
                if (String.IsNullOrEmpty(strSrc)) { return false; }
                bool _result = false;
                try
                {
                    Guid _t = new Guid(strSrc);
                    _result = true;
                }
                catch { }
                return _result;
    
            }
    

    但是大家都知道,异常捕获是要有性能损耗的。今天想了想:其实还有其它方法,也许会更好

    static bool IsGuidByReg(string strSrc)
            {
                Regex reg = new Regex("^[A-F0-9]{8}(-[A-F0-9]{4}){3}-[A-F0-9]{12}$", RegexOptions.Compiled);
                return reg.IsMatch(strSrc);
            }
    

    此外,根据Guid的格式规则:总长数36位,由4个'-'分隔,每一段都是由数字+英文字母组合而成。也可以自己写一个算法:

    static bool IsGuidByArr(string strSrc)
            {
                if (String.IsNullOrEmpty(strSrc) || strSrc.Length!=36) { return false; }
                string[] arr = strSrc.Split('-');
                if (arr.Length != 5) { return false; }
                for (int i = 0; i < arr.Length; i++)
                {
                    for (int j = 0; j < arr[i].Length; j++)
                    {
                        char a = arr[i][j];
                        if (!((a >= 48 && a <= 57) || (a >= 65 && a <= 90) || (a >= 97 && a <= 122)))
                        {
                            return false;
                        }
                    }
                }
                return true;
            }
    

    另:经猎风同学提醒,应该还要考虑到正则表达式不编译的情况,所以再加上这一段

    static bool IsGuidByRegNoComplied(string strSrc)
            {
                Regex reg = new Regex("^[A-F0-9]{8}(-[A-F0-9]{4}){3}-[A-F0-9]{12}$");
                return reg.IsMatch(strSrc);
            }
    

    此外:尘尘同学在回复中提醒到还有Guid的TryParse/Parse方法(不过该方法是.Net 4.0新增加的)

    static bool IsGuidByParse(string strSrc) 
            {
                Guid g = Guid.Empty;
                return Guid.TryParse(strSrc, out g);
            }
    

    对于猎风与尘尘的反馈表示感谢!ok,搞了这么多方法,是骡子是马,溜溜便知:

    先测试字符串格式正常的情况

    using System;
    using System.Diagnostics;
    using System.Text.RegularExpressions;
    
    namespace ConsoleApplication1
    {
        class Program
        {
    
    
            static void Main(string[] args)
            {
    
                string a = "C0869370-70BF-4408-A8CF-72A77BB1D788";           
                Console.WriteLine(IsGuidByError(a));
                Console.WriteLine(IsGuidByReg(a));
                Console.WriteLine(IsGuidByRegNoComplied(a));
                Console.WriteLine(IsGuidByArr(a));
                Console.WriteLine(IsGuidByParse(a));
                Console.WriteLine("测试开始------------------->\n");
    
    
    
                Stopwatch sw = new Stopwatch();
    
                int count = 5000;
                int times = 5;
                long result = 0;
    
                for (int i = 0; i < times; i++)
                {
                    result += Test(sw, count, a, MethodType.异常);
                }
    
    
                Console.WriteLine("\n{0}次×{1}轮测试,[异常]方法平均每轮速度:{2}\n", count, times, result / times);
    
                Console.Write("\n");
    
    
                result = 0;
    
                for (int i = 0; i < times; i++)
                {
                    result += Test(sw, count, a, MethodType.正则);
                }
    
                Console.WriteLine("\n{0}次×{1}轮测试,[正则]方法平均每轮速度:{2}\n", count, times, result / times);
    
                Console.Write("\n");
    
                result = 0;
    
                for (int i = 0; i < times; i++)
                {
                    result += Test(sw, count, a, MethodType.正则不编译);
                }
    
                Console.WriteLine("\n{0}次×{1}轮测试,[正则不编译]方法平均每轮速度:{2}\n", count, times, result / times);
    
                Console.Write("\n");
    
                result = 0;
                for (int i = 0; i < times; i++)
                {
                    result += Test(sw, count, a, MethodType.数组);
                }
    
                Console.WriteLine("\n{0}次×{1}轮测试,[数组]方法平均每轮速度:{2}\n", count, times, result / times);
    
                result = 0;
                for (int i = 0; i < times; i++)
                {
                    result += Test(sw, count, a, MethodType.TryParse);
                }
    
                Console.WriteLine("\n{0}次×{1}轮测试,[TryParse]方法平均每轮速度:{2}\n", count, times, result / times);
    
    
                Console.Read();
            }
    
    
            static bool IsGuidByArr(string strSrc)
            {
                if (String.IsNullOrEmpty(strSrc) || strSrc.Length!=36) { return false; }
                string[] arr = strSrc.Split('-');
                if (arr.Length != 5) { return false; }
                for (int i = 0; i < arr.Length; i++)
                {
                    for (int j = 0; j < arr[i].Length; j++)
                    {
                        char a = arr[i][j];
                        if (!((a >= 48 && a <= 57) || (a >= 65 && a <= 90) || (a >= 97 && a <= 122)))
                        {
                            return false;
                        }
                    }
                }
                return true;
            }
    
            static bool IsGuidByError(string strSrc)
            {
                if (String.IsNullOrEmpty(strSrc)) { return false; }
                bool _result = false;
                try
                {
                    Guid _t = new Guid(strSrc);
                    _result = true;
                }
                catch { }
                return _result;
    
            }
    
            static bool IsGuidByReg(string strSrc)
            {
                Regex reg = new Regex("^[A-F0-9]{8}(-[A-F0-9]{4}){3}-[A-F0-9]{12}$", RegexOptions.Compiled);
                return reg.IsMatch(strSrc);
            }
    
    
            static bool IsGuidByRegNoComplied(string strSrc)
            {
                Regex reg = new Regex("^[A-F0-9]{8}(-[A-F0-9]{4}){3}-[A-F0-9]{12}$");
                return reg.IsMatch(strSrc);
            }
    
    
            static bool IsGuidByParse(string strSrc) 
            {
                Guid g = Guid.Empty;
                return Guid.TryParse(strSrc, out g);
            }
    
            /// <summary>
            /// 测试
            /// </summary>
            /// <param name="sw"></param>
            /// <param name="count"></param>
            /// <param name="a"></param>
            /// <param name="useRegularExpressions"></param>
            /// <returns></returns>
            static long Test(Stopwatch sw, int count, string a, MethodType type)
            {
                bool _test = false;
                int i = 0;
                sw.Reset();
                sw.Start();
                for (i = 0; i < count; i++)
                {
                    switch (type)
                    {
                        case MethodType.异常:
                            _test = IsGuidByError(a);
                            break;
                        case MethodType.数组:
                            _test = IsGuidByArr(a);
                            break;
                        case MethodType.正则:
                            _test = IsGuidByReg(a);
                            break;
                        case MethodType.正则不编译:
                            _test = IsGuidByReg(a);
                            break;
                        case MethodType.TryParse:
                            _test = IsGuidByParse(a);
                            break;
                        default:
                            break;
                    }
                }
                sw.Stop();
                Console.Write(sw.ElapsedMilliseconds + "\n");
                return sw.ElapsedMilliseconds;
            }
    
            enum MethodType
            {
                异常,
                数组,
                正则,
                正则不编译,
                TryParse
            }
        }
    }
    

    True
    True
    True
    True
    True
    测试开始------------------->

    5
    5
    5
    5
    5

    5000次×5轮测试,[异常]方法平均每轮速度:5


    9219
    9235
    9360
    9272
    9103

    5000次×5轮测试,[正则]方法平均每轮速度:9237


    9095
    9113
    9116
    9181
    9156

    5000次×5轮测试,[正则不编译]方法平均每轮速度:9132


    9
    5
    7
    5
    6

    5000次×5轮测试,[数组]方法平均每轮速度:6

    4
    4
    4
    4
    4

    5000次×5轮测试,[TryParse]方法平均每轮速度:4

    可以看到,在字符串格式正确的情况下,异常未被触发,除正则表达式显得巨慢以外,其它三种方法相差无已。

    再来看下字符串格式错误的情况下

    string a = "C0869370-70BF-4408-A8CF-72A77BB1D788";改成string a = "C0869370-70BF-4408-A8CF-72A77BB1D788111111111111";

    输出结果如下:

    False
    False
    False
    False
    False
    测试开始------------------->

    35575
    33681
    33752
    33985
    33804

    5000次×5轮测试,[异常]方法平均每轮速度:34159


    8982
    9104
    9087
    8959
    8973

    5000次×5轮测试,[正则]方法平均每轮速度:9021


    9041
    9102
    9056
    8977
    8872

    5000次×5轮测试,[正则不编译]方法平均每轮速度:9009


    0
    0
    0
    0
    0

    5000次×5轮测试,[数组]方法平均每轮速度:0

    1
    1
    1
    1
    1

    5000次×5轮测试,[TryParse]方法平均每轮速度:1

    很明显,这时候异常带来的性能开销就很可观了,反而基于“字符数组”的检测方法最快(这跟测试用例有关,因为该字符串长度大于36,直接就出局了,连后面的循环都不用,如果换成其它错误的格式比如:“C0869370-70BF-4408-A8CF-72A77BB1D78?”,可能略有差异)

    结论:综合考虑,推荐大家用“基于字符数组”的检测方法或Guid内置的TryParse方法,异常捕获和正则表达式方法应该避免使用。

    作者:菩提树下的杨过
    出处:http://yjmyzz.cnblogs.com
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
  • 相关阅读:
    c# WF 第11节 RichTextBox
    c# WF 第10节 textbox 控件
    c# WF 第9节 button控件
    c# WF 第8节 label控件
    c# WF 第7节 对控件的基本操作
    c# WF 第6节 MDI窗体
    c# WF 第5节 窗体的控件
    Python接口自动化之动态数据处理
    Saturn分布式调度之系统架构简介
    Jmeter系列之接口依赖
  • 原文地址:https://www.cnblogs.com/yjmyzz/p/1768620.html
Copyright © 2020-2023  润新知