为什么只有有限数量的正则表达式捕获存储在“global_variables”中?
Why are only a limited number of regular expression captures stored in `global_variables`?
如果我用包含十个捕获的正则表达式进行匹配:
/(o)(t)(th)(f)(fi)(s)(se)(e)(n)(t)/.match("otthffisseent")
然后,对于 </code>,我得到:</p>
<pre><code> # => "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, :[=13=], :$PROGRAM_NAME, :$-p, :$-l,
:$-a, :$binding, :, :, :, :, :, :, :, :, :]
这里只列出前九个:
, :, :, :, :, :, :, :, :
这也得到了证实:
global_variables.include?(:) # => false
</code> 存储在哪里,为什么不存储在 <code>global_variables
中?
从 Kernel#global_variables
编辑的编号变量 return 将始终相同,即使在分配之前也是如此。 IE。 </code> 到 <code>
甚至在您进行匹配之前就会被 return 编辑,并且匹配更多的不会添加到列表中。 (它们也可以不赋值,例如使用 = "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 循环中看到符号 </code> 到 <code>
被硬编码到方法的 return 值中。
那么,如果 global_variables
的输出没有改变,你还能使用 </code> 吗?好吧,输出可能有点误导,因为它表明您的匹配数据存储在单独的变量中,但这些只是快捷方式,委托给存储在 <code>$~
.[=26= 中的 MatchData
对象]
本质上是$n
看$~[n]
。您会发现此 MatchData
对象(来自全局 table)是该方法原始输出的一部分,但在您进行匹配之前不会分配它。
至于在函数输出中包含 </code> 到 <code>
的理由是什么,您需要询问 Ruby 核心团队中的某个人。这似乎是武断的,但可能是经过深思熟虑后做出的决定。
Ruby 似乎在解析器级别处理 </code>、<code>
等:
ruby --dump parsetree_with_comment -e '0'
输出:
###########################################################
## 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: , , ..
# +- nd_nth (variable): 0
顺便说一句,maximum number of capture groups 是 32,767,您可以通过 $n
:
访问所有内容
/#{'()' * 32768}/ #=> RegexpError: too many capture groups are specified
/#{'()' * 32767}/ =~ '' #=> 0
defined? 767 #=> "global-variable"
767 #=> ""
我们将此行为视为一个错误。我们在后备箱中修复了这个问题。
如果我用包含十个捕获的正则表达式进行匹配:
/(o)(t)(th)(f)(fi)(s)(se)(e)(n)(t)/.match("otthffisseent")
然后,对于 </code>,我得到:</p>
<pre><code> # => "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, :[=13=], :$PROGRAM_NAME, :$-p, :$-l,
:$-a, :$binding, :, :, :, :, :, :, :, :, :]
这里只列出前九个:
, :, :, :, :, :, :, :, :
这也得到了证实:
global_variables.include?(:) # => false
</code> 存储在哪里,为什么不存储在 <code>global_variables
中?
从 Kernel#global_variables
编辑的编号变量 return 将始终相同,即使在分配之前也是如此。 IE。 </code> 到 <code>
甚至在您进行匹配之前就会被 return 编辑,并且匹配更多的不会添加到列表中。 (它们也可以不赋值,例如使用 = "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 循环中看到符号 </code> 到 <code>
被硬编码到方法的 return 值中。
那么,如果 global_variables
的输出没有改变,你还能使用 </code> 吗?好吧,输出可能有点误导,因为它表明您的匹配数据存储在单独的变量中,但这些只是快捷方式,委托给存储在 <code>$~
.[=26= 中的 MatchData
对象]
本质上是$n
看$~[n]
。您会发现此 MatchData
对象(来自全局 table)是该方法原始输出的一部分,但在您进行匹配之前不会分配它。
至于在函数输出中包含 </code> 到 <code>
的理由是什么,您需要询问 Ruby 核心团队中的某个人。这似乎是武断的,但可能是经过深思熟虑后做出的决定。
Ruby 似乎在解析器级别处理 </code>、<code>
等:
ruby --dump parsetree_with_comment -e '0'
输出:
###########################################################
## 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: , , ..
# +- nd_nth (variable): 0
顺便说一句,maximum number of capture groups 是 32,767,您可以通过 $n
:
/#{'()' * 32768}/ #=> RegexpError: too many capture groups are specified
/#{'()' * 32767}/ =~ '' #=> 0
defined? 767 #=> "global-variable"
767 #=> ""
我们将此行为视为一个错误。我们在后备箱中修复了这个问题。