Raku / Perl6:如何限制匹配方法来捕获组?

时间:2019-12-12 16:12:59

标签: regex raku

我正在尝试将文件名中的三个字母与1000Genomes项目匹配,并且仅将三个字符串与(...)/gcc/6.3.0/include/c++/6.3.0/array:90:12: error: no matching function for call to 'Bar::Bar()' 这样的字符串匹配,我应该只得到ethnicity_lists/PEL.txt。字符串的其余部分无关紧要。

PEL

问题在于my $p1-label = @populations[$p1-index].match(/^ethnicity_lists\/(<[A..Y]>)**3\.txt$/); 包含捕获组之外的整个字符串。

我在$p1-label周围加上括号以强调我只希望该组。

浏览https://docs.perl6.org/routine/match

我尝试尽可能具体,以防止出现任何可能的错误,这就是为什么要包含整个字符串的原因。

如果我进行Perl5风格的比赛:

<[A..Y]>

我已经尝试了if @populations[$p1-index] ~~ /^ethnicity_lists\/(<[A..Y]>)**3\.txt$/ { put $0.join(''); # strange that this outputs an array instead of a string } 方法的所有副词,但没有一个完成必要的工作。

如何将match方法限制为仅在正则表达式中的捕获组?

3 个答案:

答案 0 :(得分:7)

match方法返回一个Match对象,该对象包含有关比赛的所有信息。如果您这样做:

my $p1-label = @populations[$p1-index].match(/^ethnicity_lists\/(<[A..Y]>)**3\.txt$/);
say $p1-label;

您会看到它包含3个标记为0的项目,因为括号中提到了** 3:

「ethnicity_lists/PEL.txt」
 0 => 「P」
 0 => 「E」
 0 => 「L」

获取Match对象的Str表示形式将为您提供完整的匹配。但是您也可以要求它的[0]索引。

say  say $p1-label[0]'
[「P」 「E」 「L」]

让我们修复正则表达式,将量词放在方括号中,看看我们能得到什么。

my $p1-label = @populations[$p1-index].match(/^ethnicity_lists\/(<[A..Y]>**3)\.txt$/);
say $p1-label;
「ethnicity_lists/PEL.txt」
 0 => 「PEL」

看起来更好。现在,如果您只想要PEL位,则有两个选择。您只需获取比赛中第一项的Str表示形式即可:

my $p1-label = @populations[$p1-index].match(/^ethnicity_lists\/(<[A..Y]>**3)\.txt$/)[0].Str;
say $p1-label;
PEL

请注意,如果不将其强制转换为字符串,则会得到子匹配项的match对象。 (这可能是有用的,但不是您需要的)。

或者您可以使用零宽度断言并完全跳过捕获:

my $p1-label = @populations[$p1-index].match(/<?after ^ethnicity_lists\/><[A..Y]>**3<?before \.txt$>/).Str;
say $p1-label;
PEL

在这里,我们匹配出现在表达式{{1}之后的 之前 ^ethnicity_lists\/的3个大写字母,但它们不包含在匹配自己。

或者如@raiph所指出的,您可以使用两次捕获来告诉系统这是您唯一想要的:

\.txt$

最后一个可能是最好的。

希望有帮助。

答案 1 :(得分:6)

因为捕获组匹配多次,所以它输出一个数组。您需要将量词放在组内:

/^ethnicity_lists\/(<[A..Y]>**3)\.txt$/;
say $0; # PEL

答案 2 :(得分:6)

@Holli的答案很关键,而@Scimon则更深入地了解了为什么获得了结果,但是...

如果您双重强调<( ... )>而不是( ... )想要的部分,那么该部分将成为整个捕获对象。

如果使用put而不是say,则会得到机器友好字符串化(与.Str相同,因此在这种情况下,PEL ),而不是人类友好字符串化(与.gist相同,因此在这种情况下,它应该是「PEL」):

put 'fooPELbar' ~~ / foo  ( ... )  bar /; # fooPELbar
put 'fooPELbar' ~~ / foo <( ... )> bar /; # PEL