Mac*_*eus 3 regex perl regex-recursion
我正在编写一个简单的正则表达式,需要接收一对坐标和/或地图名称。
例如:
move 10 15 # should returns [[10, 15]]
move 10 15 map # should returns [[10, 15, 'map']]
move map # should returns [['map']]
move 10 15 mapA mapB # should returns [[10, 15, 'mapA'], ['mapB']]
move 10 15 mapA mapB 33 44 # should returns [[10, 15, 'mapA'], ['mapB'], [33, 44]]
move 10 15 mapA 33 44 mapB # should returns [[10, 15, 'mapA'], [33, 44, 'mapB']]
Run Code Online (Sandbox Code Playgroud)
然后,我写了这个正则表达式:
/
(?(DEFINE)
(?<coord> (?<x>\d+)\s+(?<y>\d+) )
(?<map> (?<mapname>[a-zA-Z]+) )
(?<commands> \s* (?: (?&coord) | (?&map) ) \s* (?&commands)? )
)
move\s+(?&commands)
/six
Run Code Online (Sandbox Code Playgroud)
但我怎么能得到群体的价值x,y并map使用Perl?
我尝试了一些方法:
use strict;
use warnings;
my $command = 'move 10 15';
$command =~ /
(?(DEFINE)
(?<coord> (?<x>\d+)\s+(?<y>\d+) )
(?<map> (?<mapname>[a-zA-Z]+) )
(?<commands> \s* (?: (?&coord) | (?&map) ) \s* (?&commands)? )
)
move\s+(?&commands)
/six;
while (my ($k,$v) = each %+) { print "$k $v\n" }
print "$+{x}";
Run Code Online (Sandbox Code Playgroud)
从问题上讲,您不能拥有它。该perlre说,这个
请注意,在递归返回后无法访问在递归内匹配的捕获组,因此捕获组的额外层是必需的。
但是此模式<x>不能再进行“额外的捕获”,因为它仅在语法内部使用。你只能拥有整个东西
if ($command =~ /
move\s+ (?<match>(?&commands))
(?(DEFINE)
(?<coord> (?<x>\d+)\s+(?<y>\d+) )
(?<map> (?<mapname>[a-zA-Z]+) )
(?<commands> \s* (?: (?&coord) | (?&map) ) \s* (?&commands)? )
)
/six)
{
say "got: $+{match}";
}
Run Code Online (Sandbox Code Playgroud)
?(DEFINED)根据建议,将块移动到模式末尾的位置。
请注意,这是没有意义之一:以递归的比赛,其中多的<x>应该一赠?因此,您需要重组方法,以便能够重新捕获所需的匹配项。但如果您希望将子图案深埋,我看不出该怎么做。
对于出现的问题,我会编写一个简单的解析器,不要介意所有正则表达式。或者,在您的方法中,重新处理其零件的匹配项,希望一旦获得匹配项,便会容易得多。
然后是功能强大的工具,例如Marpa :: R2,Parse :: RecDescent和Regexp :: Grammars。
| 归档时间: |
|
| 查看次数: |
105 次 |
| 最近记录: |