RegEx字词表现:\ w与[a-zA-Z0-9_]

艾玛

我想知道通过的字符列表\w,是[a-zA-Z0-9_]还是可以覆盖更多字符?

我问这个问题,是因为基于\d是不同的[0-9],是低效率的

\wvs [a-zA-Z0-9_]:大规模运行哪个可能更快?

池上

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

/\w/aa(实际等于/[a-zA-Z0-9_]/)通常更快,但并非总是如此。也就是说,差异是如此之小(每次检查少于1纳秒),因此不必担心。放到上下文中,调用一个子程序或启动正则表达式引擎花费的时间要长得多。

接下来的内容将对此进行详细介绍。


首先,\w[a-zA-Z0-9_]默认设置不同。\w匹配每个字母,数字,标记和连接器标点的Unicode Code Point。其中有119,821![1]确定哪个是最快的非等效代码是没有道理的。

但是,使用\wwith/aa可确保\w仅match [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\w和Unicode\w都击败了显式类。

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


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 s


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会\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会\w击败显式类。

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


结论

  • 我很惊讶/\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。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

正则表达式:/ w表示[a-zA-Z]还是[a-zA-Z0-9_],因为大多数教程都提到\ w-匹配单词字符?

python regex仅保留以字母开头并以[a-zA-Z0-9]继续的单词

解码Regex表达式-^ [a-zA-Z0-9‘&!#$%()* +,-。/:;?@ [\\] ^ _`{|}〜] + $

htaccess文件中的^(。*)$与^([a-zA-Z0-9])$

为什么/^[a-zA-Z0-9]+@[a-zA-Z0-9]\.(com)|(edu)|(org)$/i无法正常工作

正则表达式 (^|[^A-Za-z0-9])Trump([^A-Za-z0-9]|$) 含义

为什么 /^[a-zA-Z0-9_]+$/ 和 /^[a-zA-Z0-9_]{1,}$/ 接受空字符串

php regex preg_match表达式以测试A-Za-z0-9的字符串,空格字符和通用标点符号

从字符串中删除除 a-zA-Z0-9 之外的所有特殊字符

正则表达式问题^ [a-zA-Z0-9] {5,10} $

Java代码约定:必须匹配模式'^ [az] [a-zA-Z0-9] * $'

Ruby正则表达式允许A-Za-z0-9

` docker-compose up ` 无效的服务名称 '.....' - 只允许 [a-zA-Z0-9\._\-] 字符

错误:存储桶名称必须与正则表达式“ ^ [a-zA-Z0-9。\ -_] {1,255} $”匹配

正则表达式匹配几组a-zA-Z0-9-,但不匹配2个连续的下划线__

在python中仅删除连续的特殊字符,但保留连续的[a-zA-Z0-9]和单个字符

适用于A-Za-z0-9撇号,空格和连字符的正则表达式,范围

正则表达式允许 a-zA-Z0-9、空格、点、逗号、减号但不允许换行

没有参数但会强制将用户输入限制为正则表达式[a-zA-Z] [a-zA-Z0-9] *的SQL注入攻击有任何风险吗?

如何使用pregmatch验证没有字符/.%\@?在输入字段中,只有A-Za-z0-9./在另一个输入字段中

我想为字符编写正则表达式以从 a-zA-z0-9(从 1 到任何)接受一个来自 . 或者 _

字符串只能包含[a-zA-Z0-9_]符号(可以从一个字母开始,但不能从“ _”开始),不能从数字开始

為什麼我在嘗試使用 Terraform 創建 API 網關資源時得到 Resource's path part only allowed a-zA-Z0-9._-: ?

电子邮件的正则表达式用户名应以[a-zA-Z0-9]开头或结尾,但中间可能包含破折号,下划线

反向查找“详细信息”,未找到任何参数。尝试了1个模式:['product /(?P <slug> [-a-zA-Z0-9 _] +)$']

“ /”不允许状态传递给AngularJs UI路由器中的“ / {用户名:[a-zA-Z0-9] {3,20}}”

可以使[a-zA-Z] Python regex模式匹配并替换非ASCII Unicode字符吗?

正则表达式-除1-9或a-zA-Z以外的任何可打印字符

正则表达式“ ^ [A-Za-z] {2} [1-9] {2}。*”中的点是什么?