Я вчера сделал комментарий на ответ , где кто - то используется [0123456789]
в регулярном выражении , а не [0-9]
или \d
. Я сказал, что, вероятно, более эффективно использовать спецификатор диапазона или цифр, чем набор символов.
Я решил проверить это сегодня и с удивлением обнаружил, что (по крайней мере в движке C # regex) \d
, по-видимому, менее эффективен, чем любой из двух других, которые, похоже, не сильно отличаются. Вот мой тестовый вывод более 10000 случайных строк из 1000 случайных символов, причем 5077 фактически содержат цифру:
Regular expression \d took 00:00:00.2141226 result: 5077/10000
Regular expression [0-9] took 00:00:00.1357972 result: 5077/10000 63.42 % of first
Regular expression [0123456789] took 00:00:00.1388997 result: 5077/10000 64.87 % of first
Это удивляет меня по двум причинам:
- Я бы подумал, что диапазон будет реализован гораздо эффективнее, чем набор.
- Я не могу понять, почему
\d
это хуже, чем[0-9]
. Есть ли что-то большее,\d
чем просто сокращение[0-9]
?
Вот тестовый код:
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 one character 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;
}
}
}
c#
regex
performance
Уэстон
источник
источник
\d
дело с локалями. Например, иврит использует буквы для цифр.\d
, что на разных языках это не означает одно и то же. В Java, например\d
, действительно соответствует только 0-9Ответы:
\d
проверяет все цифры Unicode,[0-9]
ограничиваясь этими 10 символами. Например, персидские цифры,۱۲۳۴۵۶۷۸۹
являются примером цифр Unicode, которые сопоставляются\d
, но не совпадают[0-9]
.Вы можете создать список всех таких символов, используя следующий код:
Который генерирует:
источник
Благодарим ByteBlast за то, что он заметил это в документации. Просто изменив конструктор регулярных выражений:
Дает новые сроки:
источник
RegexOptions.ECMAScript
?ECMAScript
(\u1234
). Это «просто» сокращенные классы символов, которые меняют значение (например\d
), и сокращения / свойства Unicode, которые исчезают (как\p{N}
).От «\ d» в регулярном выражении означает цифру? :
источник
If ECMAScript-compliant behavior is specified, \d is equivalent to [0-9].
var rex = new Regex(regex, RegexOptions.ECMAScript);
делает их практически неразличимыми с точки зрения производительности.Дополнение к началу ответа от Сина Iravianian , вот версия .NET 4.5 (так как только этого выхода версии поддерживает utf16, сравните первые три строк) его кода, используя полный набор кодовых точек Unicode. Из-за отсутствия надлежащей поддержки для более высоких плоскостей Юникода многие люди не знают, что нужно всегда проверять и включать верхние плоскости Юникода. Тем не менее, они иногда содержат некоторые важные символы.
Обновить
Так
\d
как не поддерживает символы не-BMP в регулярных выражениях (спасибо xanatos ), здесь версия, которая использует базу данных символов UnicodeДает следующий вывод:
источник
Regex
не поддерживает не-BMP символы. Так что в конце проверка символов> 0xffff с регулярным выражением бесполезна.\ d проверяет все Unicode, в то время как [0-9] ограничен этими 10 символами. Если всего 10 цифр, вы должны использовать. Другие я рекомендую использовать \ d , Потому что пишу меньше.
источник