如何在一场比赛中进入比赛? [英] How do I access the captures within a match?

查看:100
本文介绍了如何在一场比赛中进入比赛?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试解析一个csv文件,并且我试图在Perl6的原始正则表达式中访问名称正则表达式.原来是零.正确的方法是什么?

I am trying to parse a csv file, and I am trying to access names regex in proto regex in Perl6. It turns out to be Nil. What is the proper way to do it?

grammar rsCSV {
    regex TOP { ( \s* <oneCSV> \s* \, \s* )* }
    proto regex oneCSV {*}
          regex oneCSV:sym<noQuote> { <-[\"]>*?  }
          regex oneCSV:sym<quoted>  { \" .*? \" } # use non-greedy match
}

my $input = prompt("Enter csv line: "); 

my $m1 = rsCSV.parse($input);
say "===========================";
say $m1;
say "===========================";
say "1 " ~ $m1<oneCSV><quoted>;  # this fails; it is "Nil"
say "2 " ~ $m1[0];
say "3 " ~ $m1[0][2];

推荐答案

详细讨论补充了克里斯托夫的答案

我正在尝试解析一个csv文件

I am trying to parse a csv file

也许您专注于学习Perl 6解析并且正在编写一些一次性的代码.但是,如果要开箱即用地分析工业强度CSV,请注意Text :: CSV模块 [1] .

Perhaps you are focused on learning Perl 6 parsing and are writing some throwaway code. But if you want industrial strength CSV parsing out of the box, please be aware of the Text::CSV modules[1].

我正在尝试访问一个命名的正则表达式

I am trying to access a named regex

如果您正在学习Perl 6解析,请注意jnthn的语法跟踪器和调试器 [2] .

If you are learning Perl 6 parsing, please be aware of jnthn's grammar tracer and debugger[2].

在Perl6中的原始正则表达式中

in proto regex in Perl6

您的问题与原始正则表达式无关.

Your issue is unrelated to it being a proto regex.

问题在于,虽然与您命名的捕获相对应的匹配对象存储在$m1中的总体匹配对象中,但它并没有精确地存储在您要查找的位置

Instead the issue is that, while the match object corresponding to your named capture is stored in the overall match object you stored in $m1, it is not stored precisely where you are looking for it.

要查看发生了什么,我将首先模拟您要尝试执行的操作.我将使用仅声明一个捕获的正则表达式,即与字符串ab匹配的命名"(也称为关联")捕获.

To see what's going on, I'll start by simulating what you were trying to do. I'll use a regex that declares just one capture, a "named" (aka "Associative") capture that matches the string ab.

given 'ab'
{
    my $m1 = m/ $<named-capture> = ( ab ) /;

    say $m1<named-capture>;
    # 「ab」
}

与命名捕获相对应的匹配对象存储在您可能希望它出现在$m1中的$m1<named-capture>处的位置.

The match object corresponding to the named capture is stored where you'd presumably expect it to appear within $m1, at $m1<named-capture>.

但是使用$m1<oneCSV>却得到了Nil.有什么作用?

But you were getting Nil with $m1<oneCSV>. What gives?

捕获有两种类型:命名(又名关联")和编号(又名位置").您在正则表达式中写的包围<oneCSV>的括号引入了 numbered 捕获:

There are two types of capture: named (aka "Associative") and numbered (aka "Positional"). The parens you wrote in your regex that surrounded <oneCSV> introduced a numbered capture:

given 'ab'
{
    my $m1 = m/ ( $<named-capture> = ( ab ) ) /; # extra parens added

    say $m1[0]<named-capture>;
    # 「ab」
}

/ ( ... ) /中的括号声明单个顶级编号的捕获.如果匹配,则相应的匹配对象存储在$m1[0]中. (如果您的正则表达式看起来像/ ... ( ... ) ... ( ... ) ... ( ... ) ... /,则与第二对括号匹配的另一个匹配对象将存储在$m1[1]中,另一个存储在$m1[2]中,用于第三对括号,依此类推.)

The parens in / ( ... ) / declare a single top level numbered capture. If it matches, then the corresponding match object is stored in $m1[0]. (If your regex looked like / ... ( ... ) ... ( ... ) ... ( ... ) ... / then another match object corresponding to what matches the second pair of parentheses would be stored in $m1[1], another in $m1[2] for the third, and so on.)

然后将$<named-capture> = ( ab )的匹配结果存储在内部 $m1[0]中.这就是say $m1[0]<named-capture>起作用的原因.

The match result for $<named-capture> = ( ab ) is then stored inside $m1[0]. That's why say $m1[0]<named-capture> works.

到目前为止,一切都很好.但这只是故事的一半...

So far so good. But this is only half the story...

在紧接上面的代码中的$m1[0]<named-capture>工作时,在原始代码的$m1[0]<oneCSV>中,您仍然仍然无法获得匹配对象.这是因为您还使用了* 量化器:

While $m1[0]<named-capture> in the immediately above code is working, you would still not get a match object in $m1[0]<oneCSV> in your original code. This is because you also asked for multiple matches of the zeroth capture because you used a * quantifier:

given 'ab'
{
    my $m1 = m/ ( $<named-capture> = ( ab ) )* /; # * is a quantifier

    say $m1[0][0]<named-capture>;
    # 「ab」
}

由于*量词要求进行多次匹配,因此Perl 6将匹配对象的列表写入$m1[0]中. (在这种情况下,只有这样一个匹配项,因此您最终得到一个长度为1的列表,即仅$m1[0][0](而不是$m1[0][1]$m1[0][2]等).)

Because the * quantifier asks for multiple matches, Perl 6 writes a list of match objects into $m1[0]. (In this case there's only one such match so you end up with a list of length 1, i.e. just $m1[0][0] (and not $m1[0][1], $m1[0][2], etc.).)

  • 捕获巢;

  • captures nest;

*+量化的捕获对应于两个嵌套级别,而不仅仅是一个.

a capture quantified by either * or + corresponds to two levels of nesting not just one.

在原始代码中,您必须编写say $m1[0][0]<oneCSV>;才能找到所需的匹配对象.

In your original code, you'd have to write say $m1[0][0]<oneCSV>; to get to the match object you're looking for.

[1] 安装相关模块,并在代码开始处编写use Text::CSV;(用于纯Perl 6实现)或use Text::CSV:from<Perl5>;(用于Perl 5 plus XS实现). (对话幻灯片(单击顶部的单词,例如"csv",以浏览幻灯片), 视频 Perl 6模块 Perl 5 XS模块.)

[1] Install relevant modules and write use Text::CSV; (for a pure Perl 6 implementation) or use Text::CSV:from<Perl5>; (for a Perl 5 plus XS implementation) at the start of your code. (talk slides (click on top word, eg. "csv", to advance through slides), video, Perl 6 module, Perl 5 XS module.)

[2] 安装相关模块,并在代码的开头写入use Grammar::Tracer;use Grammar::Debugger;. (幻灯片

[2] Install relevant modules and write use Grammar::Tracer; or use Grammar::Debugger; at the start of your code`. (talk slides, video, modules.)

这篇关于如何在一场比赛中进入比赛?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆