在学习how to pass regexes
as arguments之后,我尝试使用sub
构建我的第一个正则表达式,并且我再次陷入困境。对于下面的复杂规则感到抱歉,我已尽力简化它们。我至少需要一些线索来解决这个问题。
regex
应由更改组成,每个更改由left
,middle
和right
组成,其中left
和right
应该成对出现middle
的变体取决于选择right
。
Pairs
数组包含left
和right
对:
my Pair @leftright =
A => 'a',
...
Z => 'z',
;
从散列中读取 Middle
变体:
my Regex %middle =
z => / foo /,
a => / bar /,
m => / twi /,
r => / bin /,
...
;
如果%middle<z>
为right
,z
- 如果%middle<a>
为right
等,则应选择{p> a
因此,生成的正则表达式应该是
my token word {
| A <%middle[a]> a
| Z <%middle[z]> z
| ...
}
或更常见的
my token word {
| <left=@leftright[0].key>
<middle=%middle{@leftright[0].value}>
<right=@leftright[0].value>
| (the same for index == 1)
| (the same for index == 2)
| (the same for index == 3)
...
}
它应与Abara
和Zfooz
匹配。
如何构建token word
(可以在grammar
中使用sub
),@leftright
将从%middle{}
中获取每对,放置合适的right
取决于regex
的值,然后将它们全部合并为一个my Regex sub sub_word(Pair @l_r, Regex %m) {
...
}
my token word {
<{sub_word(@leftright, %middle)}>
}
?
left
比赛结束后,我需要知道middle
,right
和"Abara" ~~ &word;
say join '|', $<left>, $<middle>, $<right> # A|bar|a
的值:
import re
line = "7654 16.317 8.651 7.70.582 17.487"
val = line.split(" ")[3]
m = re.search('^([0-9]+\.[0-9]+).*', val)
m.group(1)
答案 0 :(得分:2)
我无法使用token
执行此操作,但此处是EVAL
和Regex
的解决方案(我还使用%middle
作为哈希Str
而不是Regex
的哈希值:
my Regex sub build_pattern (%middle, @leftrigth) {
my $str = join '|', @leftright.map(
{join ' ',"\$<left>='{$_.key}'", "\$<middle>='{%middle{$_.value}}'", "\$<right>='{$_.value}'"});
);
my Regex $regex = "rx/$str/".EVAL;
return $regex;
}
my Regex $pat = build_pattern(%middle, @leftright);
say $pat;
my $res = "Abara" ~~ $pat;
say $res;
<强>输出强>:
rx/$<left>='A' $<middle>='bar' $<right>='a'|$<left>='Z' $<middle>='foo' $<right>='z'/
「Abara」
left => 「A」
middle => 「bar」
right => 「a」
有关我选择使用EVAL
的原因的详细信息,请参阅How can I interpolate a variable into a Perl 6 regex?