首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >D效率低于[0-9]

D效率低于[0-9]
EN

Stack Overflow用户
提问于 2013-05-18 07:18:40
回答 5查看 100K关注 0票数 1.3K

昨天,我就有人在regex中使用[0123456789]而不是[0-9]\d的回答发表了评论。我说使用范围或数字说明符可能比字符集更有效。

我决定今天对此进行测试,并惊讶地发现(至少在c# regex引擎中),\d的效率似乎不如其他两者中的任何一个,这两者似乎并没有太大的不同。下面是我的测试输出,超过10000个随机字符串的1000个随机字符,其中5077实际上包含一个数字:

代码语言:javascript
复制
Regex \d           took 00:00:00.2141226 result: 5077/10000
Regex [0-9]        took 00:00:00.1357972 result: 5077/10000  63.42 % of first
Regex [0123456789] took 00:00:00.1388997 result: 5077/10000  64.87 % of first

这对我来说是一个惊喜,有两个原因,我会感兴趣的,如果有人能提供一些了解:

  1. 我原以为这个范围会比设定有效得多。
  2. 我不明白为什么\d[0-9]差。\d不仅仅是[0-9]的缩写吗?

下面是测试代码:

代码语言:javascript
复制
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
using System.Text.RegularExpressions;

namespace SO_RegexPerformance
{
    class Program
    {
        static void Main(string[] args)
        {
            var rand = new Random(1234);
            var strings = new List<string>();
            //10K random strings
            for (var i = 0; i < 10000; i++)
            {
                //generate random string
                var sb = new StringBuilder();
                for (var c = 0; c < 1000; c++)
                {
                    //add a-z randomly
                    sb.Append((char)('a' + rand.Next(26)));
                }
                //in roughly 50% of them, put a digit
                if (rand.Next(2) == 0)
                {
                    //replace 1 char with a digit 0-9
                    sb[rand.Next(sb.Length)] = (char)('0' + rand.Next(10));
                }
                strings.Add(sb.ToString());
            }

            var baseTime = testPerfomance(strings, @"\d");
            Console.WriteLine();
            var testTime = testPerfomance(strings, "[0-9]");
            Console.WriteLine("  {0:P2} of first", testTime.TotalMilliseconds / baseTime.TotalMilliseconds);
            testTime = testPerfomance(strings, "[0123456789]");
            Console.WriteLine("  {0:P2} of first", testTime.TotalMilliseconds / baseTime.TotalMilliseconds);
        }

        private static TimeSpan testPerfomance(List<string> strings, string regex)
        {
            var sw = new Stopwatch();

            int successes = 0;

            var rex = new Regex(regex);

            sw.Start();
            foreach (var str in strings)
            {
                if (rex.Match(str).Success)
                {
                    successes++;
                }
            }
            sw.Stop();

            Console.Write("Regex {0,-12} took {1} result: {2}/{3}", regex, sw.Elapsed, successes, strings.Count);

            return sw.Elapsed;
        }
    }
}
EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2013-05-18 07:24:11

\d检查所有Unicode数字,而[0-9]仅限于这10个字符。例如,波斯语数字,۱۲۳۴۵۶۷۸۹,是与\d匹配的Unicode数字的示例,而不是[0-9]

可以使用以下代码生成所有此类字符的列表:

代码语言:javascript
复制
var sb = new StringBuilder();
for(UInt16 i = 0; i < UInt16.MaxValue; i++)
{
    string str = Convert.ToChar(i).ToString();
    if (Regex.IsMatch(str, @"\d"))
        sb.Append(str);
}
Console.WriteLine(sb.ToString());

它产生:

0123456789٠١٢٣٤٥٦٧٨٩۰۱۲۳۴۵۶۷۸۹߀߁߂߃߄߅߆߇߈߉०१२३४५६७८९০১২৩৪৫৬৭৮৯੦੧੨੩੪੫੬੭੮੯૦૧૨૩૪૫૬૭૮૯୦୧୨୩୪୫୬୭୮୯௦௧௨௩௪௫௬௭௮௯౦౧౨౩౪౫౬౭౮౯೦೧೨೩೪೫೬೭೮೯൦൧൨൩൪൫൬൭൮൯๐๑๒๓๔๕๖๗๘๙໐໑໒໓໔໕໖໗໘໙༠༡༢༣༤༥༦༧༨༩၀၁၂၃၄၅၆၇၈၉႐႑႒႓႔႕႖႗႘႙០១២៣៤៥៦៧៨៩᠐᠑᠒᠓᠔᠕᠖᠗᠘᠙᥆᥇᥈᥉᥊᥋᥌᥍᥎᥏᧐᧑᧒᧓᧔᧕᧖᧗᧘᧙᭐᭑᭒᭓᭔᭕᭖᭗᭘᭙᮰᮱᮲᮳᮴᮵᮶᮷᮸᮹᱀᱁᱂᱃᱄᱅᱆᱇᱈᱉᱐᱑᱒᱓᱔᱕᱖᱗᱘᱙꘠꘡꘢꘣꘤꘥꘦꘧꘨꘩꣐꣑꣒꣓꣔꣕꣖꣗꣘꣙꤀꤁꤂꤃꤄꤅꤆꤇꤈꤉꩐꩑꩒꩓꩔꩕꩖꩗꩘꩙0123456789

票数 1.6K
EN

Stack Overflow用户

发布于 2013-05-18 09:37:17

这归功于ByteBlast在文档中注意到了这一点。只需更改regex构造函数:

代码语言:javascript
复制
var rex = new Regex(regex, RegexOptions.ECMAScript);

给出新的时间表:

代码语言:javascript
复制
Regex \d           took 00:00:00.1355787 result: 5077/10000
Regex [0-9]        took 00:00:00.1360403 result: 5077/10000  100.34 % of first
Regex [0123456789] took 00:00:00.1362112 result: 5077/10000  100.47 % of first
票数 281
EN

Stack Overflow用户

发布于 2013-05-18 07:27:14

来自“d”在regex中是指数字吗?

[0-9]并不等同于\d[0-9]只匹配0123456789字符,而\d匹配[0-9]和其他数字字符,例如东方阿拉伯数字٠١٢٣٤٥٦٧٨٩

票数 123
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/16621738

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档