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

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

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

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方法,异常捕获和正则表达式方法应该避免使用。

目录
相关文章
|
10月前
|
数据采集 监控 机器人
浅谈网页端IM技术及相关测试方法实践(包括WebSocket性能测试)
最开始转转的客服系统体系如IM、工单以及机器人等都是使用第三方的产品。但第三方产品对于转转的业务,以及客服的效率等都产生了诸多限制,所以我们决定自研替换第三方系统。下面主要分享一下网页端IM技术及相关测试方法,我们先从了解IM系统和WebSocket开始。
205 4
|
12天前
|
测试技术 开发者 Python
Python单元测试入门:3个核心断言方法,帮你快速定位代码bug
本文介绍Python单元测试基础,详解`unittest`框架中的三大核心断言方法:`assertEqual`验证值相等,`assertTrue`和`assertFalse`判断条件真假。通过实例演示其用法,帮助开发者自动化检测代码逻辑,提升测试效率与可靠性。
104 1
|
12天前
|
机器学习/深度学习 人工智能 自然语言处理
如何让AI更“聪明”?VLM模型的优化策略与测试方法全解析​
本文系统解析视觉语言模型(VLM)的核心机制、推理优化、评测方法与挑战。涵盖多模态对齐、KV Cache优化、性能测试及主流基准,助你全面掌握VLM技术前沿。建议点赞收藏,深入学习。
193 8
|
4月前
|
测试技术
软考软件评测师——可靠性测试测试方法
软件可靠性是指软件在规定条件和时间内完成预定功能的能力,受运行环境、软件规模、内部结构、开发方法及可靠性投入等因素影响。失效概率指软件运行中出现失效的可能性,可靠度为不发生失效的概率,平均无失效时间(MTTF)体现软件可靠程度。案例分析显示,嵌入式软件需满足高可靠性要求,如机载软件的可靠度需达99.99%以上,通过定量指标评估其是否达标。
|
4月前
|
消息中间件 缓存 监控
性能测试怎么做?方法、流程与核心要点解析
本文系统阐述了性能测试的核心方法论、实施流程、问题定位优化及报告编写规范。涵盖五大测试类型(负载验证、极限压力、基准比对、持续稳定性、弹性扩展)与七项关键指标,详解各阶段任务如需求分析、场景设计和环境搭建,并提供常见瓶颈识别与优化实战案例。最后规范测试报告内容框架与数据可视化建议,为企业级实践提出建立基线库、自动化回归和全链路压测体系等建议,助力高效开展性能测试工作。
|
8月前
|
编解码 缓存 Prometheus
「ximagine」业余爱好者的非专业显示器测试流程规范,同时也是本账号输出内容的数据来源!如何测试显示器?荒岛整理总结出多种测试方法和注意事项,以及粗浅的原理解析!
本期内容为「ximagine」频道《显示器测试流程》的规范及标准,我们主要使用Calman、DisplayCAL、i1Profiler等软件及CA410、Spyder X、i1Pro 2等设备,是我们目前制作内容数据的重要来源,我们深知所做的仍是比较表面的活儿,和工程师、科研人员相比有着不小的差距,测试并不复杂,但是相当繁琐,收集整理测试无不花费大量时间精力,内容不完善或者有错误的地方,希望大佬指出我们好改进!
496 16
「ximagine」业余爱好者的非专业显示器测试流程规范,同时也是本账号输出内容的数据来源!如何测试显示器?荒岛整理总结出多种测试方法和注意事项,以及粗浅的原理解析!
|
8月前
|
人工智能 自然语言处理 测试技术
AxBench:斯坦福大学推出评估语言模型控制方法的基准测试框架
AxBench 是由斯坦福大学推出,用于评估语言模型可解释性方法的基准测试框架,支持概念检测和模型转向任务,帮助研究者系统地比较不同控制技术的有效性。
168 5
AxBench:斯坦福大学推出评估语言模型控制方法的基准测试框架
|
8月前
|
SQL Java 测试技术
C#字符串拼接的6种方式及其性能分析对比
在C#编程中字符串拼接是一种常见且基础的操作,广泛应用于各种场景,如动态生成SQL查询、构建日志信息、格式化用户显示内容等。然而,不同的字符串拼接方式在性能和内存使用上可能存在显著差异。今天咱们一起来看看在C#中字符串拼接的常见6种方式及其使用BenchmarkDotNet进行性能分析对比。
114 6
|
10月前
|
开发框架 .NET Java
C#集合数据去重的5种方式及其性能对比测试分析
C#集合数据去重的5种方式及其性能对比测试分析
118 11