c#測試字串是否為GUID的幾種方法

來源:互聯網
上載者:User

以前為了趕項目遇到這種需求時,也沒過多考慮效能因素,隨便寫了一個(現在看起來很原始的)方法來實現:

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

另:經獵風同學提醒,應該還要考慮到Regex不編譯的情況,所以再加上這一段

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

可以看到,在字串格式正確的情況下,異常未被觸發,除Regex顯得巨慢以外,其它三種方法相差無已。

 

再來看下字串格式錯誤的情況下

把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方法,異常捕獲和Regex方法應該避免使用。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.