che*_*nyf 9 match smartmatch raku comb
我想提取行键(这里是28_2820201112122420516_000000)、列名(这里是bcp_startSoc)和值(这里是64.0)$str,其中$str是 HBase 中的一行:
# `match` is OK
my $str = '28_2820201112122420516_000000 column=d:bcp_startSoc, timestamp=1605155065124, value=64.0';
my $match = $str.match(/^ ([\d+]+ % '_') \s 'column=d:' (\w+) ',' \s timestamp '=' \d+ ',' \s 'value=' (<-[=]>+) $/);
my @match-result = $match».Str.Slip;
say @match-result; # Output: [28_2820201112122420516_000000 bcp_startSoc 64.0]
# `smartmatch` is OK
# $str ~~ /^ ([\d+]+ % '_') \s 'column=d:' (\w+) ',' \s timestamp '=' \d+ ',' \s 'value=' (<-[=]>+) $/
# say $/».Str.Array; # Output: [28_2820201112122420516_000000 bcp_startSoc 64.0]
# `comb` is NOT OK
# A <( token indicates the start of the match's overall capture, while the corresponding )> token indicates its endpoint.
# The <( is similar to other languages \K to discard any matches found before the \K.
my @comb-result = $str.comb(/<( [\d+]+ % '_' )> \s 'column=d:' <(\w+)> ',' \s timestamp '=' \d+ ',' \s 'value=' <(<-[=]>+)>/);
say @comb-result; # Expect: [28_2820201112122420516_000000 bcp_startSoc 64.0], but got [64.0]
Run Code Online (Sandbox Code Playgroud)
我想comb跳过一些匹配项,只匹配我想要的,所以我在这里使用多个<(和)>这里,但只得到最后一个匹配项作为结果。
是否可以使用comb获得与match方法相同的结果?
TL;DR多个<(...)>s 并不意味着多次捕获。即使他们这样做了,.comb也会将每个匹配项减少为它返回的字符串列表中的单个字符串。如果您确实想使用.comb,一种方法是返回到原始正则表达式,但也使用正则表达式中的附加代码存储所需的数据。
<(...)>s 并不意味着多次捕获正则表达式整体匹配的默认起点是正则表达式的开头。默认终点为终点。
\n写入<(会将整个匹配的起点重置为您插入的位置。每次插入一个并在正则表达式处理过程中应用它时,它都会重置起点。同样)>重置终点。在处理正则表达式结束时,开始和结束的最终设置将应用于构建最终的整体匹配。
鉴于您的代码只是无条件地重置每个点三次,最后一次开始和结束重置“win”。
\n.comb将每个匹配项减少为单个字符串foo.comb(/.../)相当于foo.match(:g, /.../)>>.Str;.
这意味着对于正则表达式的每次匹配,您只能得到一个字符串。
\n一种可能的解决方案是使用@ohmycloudy 在他们的答案中显示的方法。
\n但这伴随着我和@jubilatious1 在他们的答案的评论中提出的警告。
\n{ @comb-result .push: |$/\xc2\xbb.Str }到正则表达式您可以解决该问题.comb的正常运行。我并不是说这是一件好事。我也不是说不是。你问,我回答,仅此而已。:)
从与其他解决方案配合使用的原始正则表达式开始。
\n然后添加{ @comb-result .push: |$/\xc2\xbb.Str }到正则表达式的末尾来存储每个匹配的结果。现在您将得到您想要的结果。