zoukankan      html  css  js  c++  java
  • 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
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
  • 相关阅读:
    第二十九课 循环链表的实现
    第二十八课 再论智能指针(下)
    第二十七课 再论智能指针(上)
    第二十六课 典型问题分析(Bugfix)
    普通new和placement new的重载
    leetcode 581. Shortest Unsorted Continuous Subarray
    leetcode 605. Can Place Flowers
    leetcode 219. Contains Duplicate II
    leetcode 283. Move Zeroes
    leetcode 217. Contains Duplicate
  • 原文地址:https://www.cnblogs.com/yjmyzz/p/1768620.html
Copyright © 2011-2022 走看看