Regex 如何匹配perl6语法中的十六进制数组

Regex 如何匹配perl6语法中的十六进制数组,regex,grammar,raku,Regex,Grammar,Raku,我有一个类似于“393a3b9:;”的字符串,我想提取“393a3b” 我试过了 my $a = "39 3A 3B 9:;"; grammar Hex { token TOP { <hex_array>+ .* } token hex_array { <[0..9 A..F]> " " } }; Hex.parse($a); 如果不需要使用语法,可以执行以下操作: my $a = "39 3A 3B 9:;"; say $a.split(/\s+/

我有一个类似于
“393a3b9:;”
的字符串,我想提取“393a3b”

我试过了

my $a = "39 3A 3B  9:;";
grammar Hex {
    token TOP { <hex_array>+ .* }
    token hex_array { <[0..9 A..F]> " " }
};
Hex.parse($a);

如果不需要使用语法,可以执行以下操作:

my $a = "39 3A 3B  9:;";
say $a.split(/\s+/).grep: * ~~ /<< <[0..9 A..F]> ** 2 >>/;
my$a=“39 3A 3B 9:;”;
说$a.split(/\s+/).grep:~~~/>/;
正则表达式将匹配这些2位六进制字符串。无论如何,你的语法问题可能在于你使用的空格数量;从这个意义上讲,它们是非常严格的。

在P6正则表达式中,是匹配一个字符意义上的“字符类”。1

获取所需内容的惯用方法是:

我们添加了方括号(
[…]
),它组合了
十六进制数组和一个空格,然后将
+
量词应用于组合的原子。这是一个简单的更改,语法仍像以前一样工作,与空间匹配,但现在空间不会被
hex\u数组
标记捕获

接下来,让我们切换到使用内置的
令牌

  token TOP { [ <hex_array> <.ws> ]+ }
如果没有
:sigspace
(因此默认情况下在
token
s和
regex
s中),将忽略模式中的所有文字空格(除非您引用它们)。这通常适用于单个
标记的可读模式,因为它们通常指定要匹配的文本内容

但是一旦
:sigspace
生效,原子之后的空格就变得“重要”——因为它们被隐式转换为
[…]
调用。这对于指定令牌或子规则序列的可读模式是可取的,因为这是避免所有这些额外调用的混乱的自然方式

下面的第一个模式将匹配一个或多个
hex_数组
令牌,它们之间或末尾都不匹配空格。最后两个将匹配一个或多个
hex_数组
s,不插入空格,然后在最末端有空格或没有空格:

  token TOP {           <hex_array>+ }
  #          ^ ignored ^            ^ ignored

  token TOP { :sigspace <hex_array>+ }
  #          ^ ignored ^            ^ significant

  rule TOP  {           <hex_array>+ }
  #          ^ ignored ^            ^ significant
但是,如果您的输入有多个
hex\u数组
标记,且标记之间有一个或多个空格,则此重写标记将不匹配。相反,你会想写:

  rule TOP { <hex_array> + }
  # ignored ^           ^ ^ both these spaces are significant

ww
是一种“字里行间”测试。所以
的意思是不在一个“单词”内<代码> <代码>在代码< > **>代码>的情况下总是成功的,除了与<代码> **/COD>不同,它不会在一个词的中间成功。(像任何用
*
量化的原子一样,普通的
\s*
总是匹配的,因为它匹配任意数量的空格,包括一个都不匹配。)

我确实想使用语法,因为这是更大语法的一部分。@tejas您仍然可以将此代码用作操作。无论如何,raiph的解决方案是好的。还可以查看正则表达式,它将匹配单词边界分隔的六位数字。作为旁注,这非常缓慢,我不得不使用语法和拆分的混合。我用语法把“393a3b”作为一个整体,然后把它分开<代码>用于拆分(“,$str){$buf.push(:16($);}
Hi@tejas。感谢reddit提供给我的数据/代码。我已经回复了那里的代码,但是注意到你最近一次公开的reddit评论是在几个月前,所以我在这里打电话给你,让你去看看那里。我期待着听到它的表现。:)如果它对读者有用。
  token TOP { [ <hex_array> " " ]+ }
  token hex_array { <[0..9 A..F]>**1..2 }
  token TOP { [ <hex_array> <.ws> ]+ }
rule  {           <hex_array>+ }
token { :sigspace <hex_array>+ } # exactly the same thing
  token TOP {           <hex_array>+ }
  #          ^ ignored ^            ^ ignored

  token TOP { :sigspace <hex_array>+ }
  #          ^ ignored ^            ^ significant

  rule TOP  {           <hex_array>+ }
  #          ^ ignored ^            ^ significant
  token TOP { <hex_array>+ <.ws> }
  rule TOP { <hex_array> + }
  # ignored ^           ^ ^ both these spaces are significant
  token TOP { [ <hex_array> <.ws> ]+ <.ws> }
my $a = "39 3A 3B ";
grammar Hex {
  rule TOP { <hex_array> + }
  token hex_array { <[0..9 A..F]>**1..2 }
};
Hex.parse($a);
regex ws { <!ww> \s* }