当前位置:  开发笔记 > 后端 > 正文

为什么只有有限数量的正则表达式捕获存储在`global_variables`中?

如何解决《为什么只有有限数量的正则表达式捕获存储在`global_variables`中?》经验,为你挑选了2个好方法。

如果我匹配带有十个捕获的正则表达式:

/(o)(t)(th)(f)(fi)(s)(se)(e)(n)(t)/.match("otthffisseent")

然后,因为$10,我得到:

$10 # => "t"

但它缺少了global_variables.我得到(在irb会话中):

[:$;, :$-F, :$@, :$!, :$SAFE, :$~, :$&, :$`, :$', :$+, :$=, :$KCODE, :$-K, :$,,
 :$/, :$-0, :$\, :$_, :$stdin, :$stdout, :$stderr, :$>, :$<, :$., :$FILENAME,
 :$-i, :$*, :$?, :$$, :$:, :$-I, :$LOAD_PATH, :$", :$LOADED_FEATURES,
 :$VERBOSE, :$-v, :$-w, :$-W, :$DEBUG, :$-d, :$0, :$PROGRAM_NAME, :$-p, :$-l,
 :$-a, :$binding, :$1, :$2, :$3, :$4, :$5, :$6, :$7, :$8, :$9]

这里只列出前九个:

$1, :$2, :$3, :$4, :$5, :$6, :$7, :$8, :$9

这也得到以下证实:

global_variables.include?(:$10) # => false

$10存储在哪里,为什么不存储global_variables



1> Stefan..:

红宝石似乎处理$1,$2等在语法分析器级别:

ruby --dump parsetree_with_comment -e '$100'

输出:

###########################################################
## Do NOT use this node dump for any purpose other than  ##
## debug and research.  Compatibility is not guaranteed. ##
###########################################################

# @ NODE_SCOPE (line: 1)
# | # new scope
# | # format: [nd_tbl]: local table, [nd_args]: arguments, [nd_body]: body
# +- nd_tbl (local table): (empty)
# +- nd_args (arguments):
# |   (null node)
# +- nd_body (body):
#     @ NODE_NTH_REF (line: 1)
#     | # nth special variable reference
#     | # format: $[nd_nth]
#     | # example: $1, $2, ..
#     +- nd_nth (variable): $100

顺便说一下,最大捕获组数是32,767,你可以访问所有通过$n:

/#{'()' * 32768}/       #=> RegexpError: too many capture groups are specified

/#{'()' * 32767}/ =~ '' #=> 0
defined? $32767         #=> "global-variable"
$32767                  #=> ""


[PCRE2支持65,535个捕获组](http://stackoverflow.com/a/33928343/3832970),所以它胜过Ruby :)但是,我怀疑你将使用超过99,在现实生活中,我们宁愿得到多次匹配,而不是试图用一个笨重的正则表达式捕获所有细节.
Ruby的惊人力量.我永远不会用完捕获组.

2> Drenmi..:

返回的编号变量Kernel#global_variables将始终相同,即使在分配之前也是如此.即$1通过$9将你在比赛之前就被退回,并匹配更不会添加到列表中.(它们也不能分配,例如使用$10 = "foo".)

考虑该方法的源代码:

VALUE
rb_f_global_variables(void)
{
    VALUE ary = rb_ary_new();
    char buf[2];
    int i;

    st_foreach_safe(rb_global_tbl, gvar_i, ary);
    buf[0] = '$';

    for (i = 1; i <= 9; ++i) {
        buf[1] = (char)(i + '0');
        rb_ary_push(ary, ID2SYM(rb_intern2(buf, 2)));
    }

    return ary;
}

您可以(在习惯于查看C之后)从for循环中看到符号$1通过$9被硬编码到方法的返回值中.

那么怎么样$10,如果输出global_variables没有变化,你还可以使用吗?好吧,输出可能有点误导,因为它会建议你的匹配数据存储在单独的变量中,但这些只是快捷方式,委托给MatchData存储的对象$~.

基本上$n$~[n].您会发现此MatchData对象(来自全局表)是该方法的原始输出的一部分,但在您进行匹配之前不会分配它.

至于是什么理由,包括$1通过$9在函数的输出,你需要问在Ruby核心团队的人.这似乎是武断的,但可能会有一些审议进入决策.


@Drenmi ruby​​specs这样说https://github.com/ruby/rubyspec/blob/f8358bd32e6d2c492f8d7e7bb5a35524d2756c3c/language/predefined_spec.rb#L89
@Wand Maker它是一个"全局变量"尝试`定义?($ 10)`:)
推荐阅读
mobiledu2402851323
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有