gpt4 book ai didi

c# - RegEx 字表现 :\w vs [a-zA-Z0-9_]

转载 作者:行者123 更新时间:2023-11-30 13:43:27 25 4
gpt4 key购买 nike

我想知道 \w 传递的字符列表,是不是 [a-zA-Z0-9_]或者它可能涵盖更多的字符?

我问这个问题,因为基于 this , \d[0-9] 不同,是less efficient .

\w vs [a-zA-Z0-9_]: which one might be faster in large scale?

最佳答案

[ 这个答案是特定于 Perl 的。其中的信息可能不适用于 PCRE 或其他标记语言使用的引擎。 ]

/\w/aa(实际等效于 /[a-zA-Z0-9_]/)通常更快,但并非总是如此。也就是说,差异是如此之小(每次检查不到 1 纳秒),因此不必担心。换句话说,调用 sub 或启动正则表达式引擎需要的时间要长得多。

下面将对此进行详细介绍。


首先,默认情况下,\w[a-zA-Z0-9_] 不同。 \w 匹配每个字母、数字、标记和连接符标点 Unicode 代码点。有 119,821 个这样的代码![1] 确定哪个非等效代码最快是没有意义的。

但是,将 \w/aa 一起使用可确保 \w 仅匹配 [a-zA-Z0-9_] 。这就是我们将要用于基准测试的内容。 (实际上,我们将同时使用两者。)

(请注意,每个测试执行 1000 万次检查,因此 10.0/s 实际上意味着每秒 1000 万次检查。)


ASCII-only positive match
Rate [a-zA-Z0-9_] (?u:\w) (?aa:\w)
[a-zA-Z0-9_] 39.1/s -- -26% -36%
(?u:\w) 52.9/s 35% -- -13%
(?aa:\w) 60.9/s 56% 15% --

当在 ASCII 字符中找到匹配项时,ASCII-only \w 和 Unicode \w 都击败了显式类。

/\w/aa 在我的机器上是 ( 1/39.1 - 1/60.9 )/10,000,000 = 0.000,000,000,916 秒


ASCII-only negative match
Rate (?u:\w) (?aa:\w) [a-zA-Z0-9_]
(?u:\w) 27.2/s -- -0% -12%
(?aa:\w) 27.2/s 0% -- -12%
[a-zA-Z0-9_] 31.1/s 14% 14% --

当无法在 ASCII 字符中找到匹配项时,显式类胜过 ASCII-only \w

/[a-zA-Z0-9_]/ 在我的机器上是 ( 1/27.2 - 1/31.1 )/10,000,000 = 0.000,000,000,461 秒


Non-ASCII positive match
Rate (?u:\w) [a-zA-Z0-9_] (?aa:\w)
(?u:\w) 2.97/s -- -100% -100%
[a-zA-Z0-9_] 3349/s 112641% -- -9%
(?aa:\w) 3664/s 123268% 9% --

哇哦。该测试似乎正在进行一些优化。也就是说,多次运行测试会产生极其一致的结果。 (其他测试也是如此。)

在非 ASCII 字符中找到匹配项时,ASCII-only \w 胜过显式类。

/\w/aa 在我的机器上是 ( 1/3349 - 1/3664 )/10,000,000 = 0.000,000,000,002,57 s


Non-ASCII negative match
Rate (?u:\w) [a-zA-Z0-9_] (?aa:\w)
(?u:\w) 2.66/s -- -9% -71%
[a-zA-Z0-9_] 2.91/s 10% -- -68%
(?aa:\w) 9.09/s 242% 212% --

当无法在非 ASCII 字符中找到匹配项时,ASCII-only \w 胜过显式类。

/[a-zA-Z0-9_]/ 在我的机器上是 ( 1/2.91 - 1/9.09 )/10,000,000 = 0.000,000,002,34 秒


结论

  • 我很惊讶 /\w/aa/[a-zA-Z0-9_]/ 之间有任何区别。
  • 在某些情况下,/\w/aa 更快;在其他情况下,/[a-zA-Z0-9_]/
  • /\w/aa/[a-zA-Z0-9_]/ 之间的差异非常小(小于 1 纳秒)。
  • 差别很小,您不必担心。
  • 即使 /\w/aa/\w/u 之间的差异也很小,尽管后者匹配的字符比前者多 4 个数量级。

use strict;
use warnings;
use feature qw( say );

use Benchmarks qw( cmpthese );

my %pos_tests = (
'(?u:\\w)' => '/^\\w*\\z/u',
'(?aa:\\w)' => '/^\\w*\\z/aa',
'[a-zA-Z0-9_]' => '/^[a-zA-Z0-9_]*\\z/',
);

my %neg_tests = (
'(?u:\\w)' => '/\\w/u',
'(?aa:\\w)' => '/\\w/aa',
'[a-zA-Z0-9_]' => '/[a-zA-Z0-9_]/',
);

$_ = sprintf( 'use strict; use warnings; our $s; for (1..1000) { $s =~ %s }', $_)
for
values(%pos_tests),
values(%neg_tests);

local our $s;

say "ASCII-only positive match";
$s = "J" x 10_000;
cmpthese(-3, \%pos_tests);

say "";

say "ASCII-only negative match";
$s = "!" x 10_000;
cmpthese(-3, \%neg_tests);

say "";

say "Non-ASCII positive match";
$s = "\N{U+0100}" x 10_000;
cmpthese(-3, \%pos_tests);

say "";

say "Non-ASCII negative match";
$s = "\N{U+2660}" x 10_000;
cmpthese(-3, \%neg_tests);

  1. Unicode 版本 11。

关于c# - RegEx 字表现 :\w vs [a-zA-Z0-9_],我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55699393/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com