Regex 如何访问匹配中的捕获?
我试图解析一个csv文件,并试图访问Perl6中proto regex中的名称regex。结果是零。正确的方法是什么Regex 如何访问匹配中的捕获?,regex,match,raku,named,Regex,Match,Raku,Named,我试图解析一个csv文件,并试图访问Perl6中proto regex中的名称regex。结果是零。正确的方法是什么 grammar rsCSV { regex TOP { ( \s* <oneCSV> \s* \, \s* )* } proto regex oneCSV {*} regex oneCSV:sym<noQuote> { <-[\"]>*? } regex oneCSV:sym<qu
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];
语法rsCSV{
正则表达式TOP{(\s*\s*\,\s*)*}
proto regex oneCSV{*}
regex oneCSV:sym{匹配的
位于捕获组的范围内,您可以通过$m1[0]
获得该组
由于使用*
对组进行量化,结果将再次成为一个列表,即您需要另一个索引操作来获取匹配对象,例如第一个对象的$m1[0][0]
然后可以通过名称访问命名的捕获,例如$m1[0][0]
。这将包含protoregex的相应分支的匹配结果
如果您想要完整的匹配列表而不是特定的匹配列表,您可以使用>
或map
,例如$m1[0]>.
详细讨论补充Christoph的答案
我正在尝试解析csv文件
也许您正专注于学习Perl 6解析,并正在编写一些一次性代码。但是,如果您希望工业级CSV解析开箱即用,请注意Text::CSV模块[1]
我正在尝试访问一个命名的正则表达式
如果您正在学习Perl 6解析,请注意jnthn的语法跟踪器和调试器[2]
在Perl6的proto regex中
你的问题与它是一个原始正则表达式无关
相反,问题在于,虽然与命名捕获相对应的匹配对象存储在您存储在$m1
中的整体匹配对象中,但它并没有准确地存储在您要查找它的位置
与捕获相对应的匹配对象出现在哪里?
要了解发生了什么,我将首先模拟您试图执行的操作。我将使用一个只声明一个捕获的正则表达式,一个与字符串ab
匹配的“命名”(也称为“关联”)捕获
given 'ab'
{
my $m1 = m/ $<named-capture> = ( ab ) /;
say $m1<named-capture>;
# 「ab」
}
/(…)/
中的参数声明一个顶级编号的捕获。如果匹配,则相应的匹配对象存储在$m1[0]
中(如果您的正则表达式看起来像/…(…)(…)…/
然后与第二对括号匹配的另一个匹配对象将存储在$m1[1]
中,第三对括号对应的另一个匹配对象将存储在$m1[2]
中,依此类推。)
$=(ab)
的匹配结果随后存储在$m1[0]
中。这就是为什么说$m1[0]
起作用的原因
到目前为止还不错,但这只是故事的一半
为什么代码中的$m1[0]
也不起作用
当上述代码中的$m1[0]
起作用时,您仍然无法在原始代码中的$m1[0]
中获得匹配对象。这是因为您使用了*
,因此还要求对第零次捕获进行多个匹配:
给定“ab”
{
my$m1=m/($=(ab))*/;#*是一个量词
表示为1美元[0][0];
#ab
}
由于*
量词要求多个匹配,Perl 6将一个匹配对象列表写入$m1[0]
(在这种情况下,只有一个这样的匹配,因此最终的列表长度为1,即只有$m1[0][0]
(而不是$m1[0][1]
,$m1[0][2]
)
总结
- 捕捉鸟巢
- 通过
或*
量化的捕获对应于两个嵌套级别,而不仅仅是一个+
- 在原始代码中,必须编写
才能找到要查找的匹配对象比如$m1[0][0];
[1] 安装相关模块,并在代码开头编写
使用Text::CSV;
(对于纯Perl 6实现)或使用Text::CSV:from;
(对于Perl 5 plus XS实现)。((单击顶部的单词,例如“CSV”,浏览幻灯片),,)
[2] 安装相关模块并在代码开头编写
use Grammar::Tracer;
或use Grammar::Debugger;
。(,)非常感谢,raiph!!!在您详细解释之后,我现在看到了我的问题。非常感谢您抽出时间!!!@lisprogtor不客气。如果您能告诉我具体是哪一位的话是/是对您最有帮助的,这对我特别有帮助。:)谢谢raiph。这是您对命名/编号捕获和匹配对象树之间的关联的解释,以及perl6使用*构造列表而不是单个对象的事实。再次感谢!感谢Christoph。您的帮助加深了我对Perl 6的理解答案!
given 'ab'
{
my $m1 = m/ ( $<named-capture> = ( ab ) ) /; # extra parens added
say $m1[0]<named-capture>;
# 「ab」
}
given 'ab'
{
my $m1 = m/ ( $<named-capture> = ( ab ) )* /; # * is a quantifier
say $m1[0][0]<named-capture>;
# 「ab」
}