我正在尝试将文件名中的三个字母与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
方法限制为仅在正则表达式中的捕获组?
答案 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