当前位置:  开发笔记 > 编程语言 > 正文

perl6如何仅在某些条件下匹配角色?

如何解决《perl6如何仅在某些条件下匹配角色?》经验,为你挑选了1个好方法。

我有一个格式的文件:

- foo bar - baz
  one two three - or four
  and another line

- next job
  do this - and that

我的语法是

grammar tasks {
    regex TOP        { \n* + \n* }
    regex oneTask    { ^^ \- ( )+ }
    regex oneSection { \N+ } # this is not quite working
    regex endSection { \n+ }

}

在正则表达式oneSection中,我如何编写"我想匹配' - '只有当它不在一行开头时"的事实?

我把文件放入一个字符串并解析这个字符串:

my $content = slurp("taskFile");
my $result = tasks.parse($content);

这不太合适.

<[\N] - [\-]> does not make the match conditional.

谢谢 !!



1> Brad Gilbert..:

更容易放下你想要匹配的东西而不是试图排除某些东西.

你要找的是一行不是换行符或短划线的一个字符,后跟任意数量的非换行符.或者您正在寻找至少一个不是新行之后的换行符.

regex oneSection {

    || ^^            # beginning of line
       <-[\n-]>      # not newline or dash
       \N*           # any number of not newlines

    ||   # check the position before this is not the start of a line
       \N+

}

(这太复杂了,因为你试图将复杂性放在语法中的错误位置)


您也可以像当前一样进行匹配,如果以a开头,则添加一个失败的测试-.

regex oneSection {
    \N+

    
}

语法是一种类,正则表达式/标记/规则是一种方法.所以你应该通过添加换行符和注释来这样写.

如果您学习如何使用%%%正则表达式运算符,编写语法会更好.
(差异%%可以匹配尾随分隔符)

%有效地使用可能需要一些时间来适应,所以我将向您展示我将如何使用它来匹配您的文件.

我还将部分的分隔符从仅换行更改为换行符和两个空格.这将从section匹配中删除空格,这将简化任何进一步处理.

在学习的过程中,我建议使用Grammar :: Debugger和Grammar :: Tracer.

grammar Tasks {
    # use token for its :ratchet behaviour
    # ( more performant than regex because it doesn't backtrack )
    token TOP {
        \n*       # ignore any preceding empty lines

        +   # at least one task
        %         # separated by
        \n+       # at least one newline

        \n*       # ignore trailing empty lines
    }

    token task {
      ^^ '- '     # a task starts with ?- ? at the beginning of a line

      
+ # has at least one section % # separated by "\n " # a newline and two spaces } token section { \N+ } }
my $test = q:to/END/;
- foo bar - baz
  one two three - or four
  and another line

- next job
  do this - and that
END

put Tasks.parse( $test, :actions(class {
  method TOP     ($/) { make @».made.List }
  method task    ($/) { make @
».made.List } method section ($/) { make ~$/ # don't do any processing, just make it a Str } })).made.perl; # (("foo bar - baz", "one two three - or four", "and another line"), # ("next job", "do this - and that"))

如果我放在use Grammar::Tracer;顶部,这就是输出的内容:

TOP
|  task
|  |  section
|  |  * MATCH "foo bar - baz"
|  |  section
|  |  * MATCH "one two three - or four"
|  |  section
|  |  * MATCH "and another line"
|  * MATCH "- foo bar - baz\n  one two three - or four\n  and another l"
|  task
|  |  section
|  |  * MATCH "next job"
|  |  section
|  |  * MATCH "do this - and that"
|  * MATCH "- next job\n  do this - and that"
|  task
|  * FAIL
* MATCH "- foo bar - baz\n  one two three - or four\n  and another line"

FAIL是预期的,因为有一个尾随换行符,并且语法知道后可以跟着一个任务.

推荐阅读
jerry613
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有