在perl6语法中放宽空格的最佳方法是什么?

p6s*_*eve 11 perl6

我想拥有一个语法,它是否存在空格...我想匹配:

this                '   <foo>    <bar>    <baz>    '
and also this       '<foo><bar><baz>'
Run Code Online (Sandbox Code Playgroud)

这有效:

token TOP     { \s* <foo> \s* <bar> \s* <baz> \s* }
Run Code Online (Sandbox Code Playgroud)

但是,在阅读了有关:sigspace, <。ws >规则的所有信息之后,我可以想象有一种方法可以避免重复的* \ s。(即,如何在per6语法中匹配十六进制数组

请问有人可以告诉我在perl6语法中是否还有更好的方法?

注意 这不能通过简单地将令牌声明更改为rule来解决 -当我尝试这种方法时,解析字符串中要么匹配空格,要么不匹配空格(但不能同时匹配两个)。

rai*_*iph 11

也许您的问题是这三个规则“ gotchyas”之一:

  • 如果要在规则的开头一个 atom 之前匹配空白/令牌边界,则必须显式提供(通常是显式<.ws>)。

  • 如果要量化的原子(例如)的每个匹配项之间进行空格/标记边界匹配,则<foo>*必须在原子和量词(例如<foo> *)之间包括空格。

  • 默认<ws>定义为regex ws { <!ww> \s* }。如果您希望rule特定语法中的S使用其他模式,请在该语法中定义自己的语法。(timotimo ++)

有关上述内容的进一步讨论,请参阅我如何在per6语法中匹配十六进制数组的更新答案。


以下四个正则表达式匹配您的两个示例字符串:

my \test-strings := '   <foo>    <bar>    <baz>    ', '<foo><bar><baz>';

my \test-regexes := token { \s*   '<foo>' \s* '<bar>' \s* '<baz>' \s* },
                    rule  { \s*   '<foo>' \s* '<bar>' \s* '<baz>' \s* },
                    rule  { \s*   '<foo>'     '<bar>'     '<baz>'     },
                    rule  { <.ws> '<foo>'     '<bar>'     '<baz>'     }

say (test-strings X~~ test-regexes).all ~~ Match # True
Run Code Online (Sandbox Code Playgroud)

  • 如果没有空格,并且如果不是字面意义上要匹配的“ &lt;foo&gt;”,而是“某物”,那么默认的“ &lt;ws&gt;”规则也要求单词边界。问题。因此,在这种情况下,将自己的ws定义为`\ s *`就可以解决问题 (2认同)