我试图将系统宏的以下EBNF文法编码为正则表达式(如下所示),但尽管我尽了最大的努力,它似乎还是在多个宏之间贪婪地匹配:它不会在关闭}}@时停止。
Expand ``@{{...}}@`` references which may appear in Step parameters.
The syntax is described by the following EBNF grammar::
depdata = "@{{", source identifier, ":", attribute, "}}@"
| "@{{TAGS:", expression, "}}@" ;
source identifier = ? printable 7-bit ASCII ? ;
attribute = "DATADIR" | "TAGSFILE" | "RESULT_INT" ;
expression = ? printable 7-bit ASCII ? ;和我想出的Python正则表达式
@{{(?:(?:(?P<id>.*?):(?P<attr>DATADIR|TAGSFILE|RESULT_INT))|TAGS:(?P<expr>.+?))}}@编辑:在expr组中添加缺失的+

当在下面的测试用例中找到所有匹配时,我希望结果是三个匹配,但我只得到两个:
@{{TAGS:sTagsJob << "job||ID||source"}}@ test @{{job:DATADIR}}@ email body @{{job:DATADIR}}@ blah我期望的比赛是:
@{{TAGS:sTagsJob << "job||ID||source"}}@组集的expr@{{job:DATADIR}}@和attr组的id@{{job:DATADIR}}@ (再次),设置了id和attr组但与之相反的是:
@{{TAGS:sTagsJob << "job||ID||source"}}@ test @{{job:DATADIR}}@@{{job:DATADIR}}@为什么非贪婪的火柴(.+?)似乎是贪婪的?我错过了什么?
(是的,我知道EBNF语法很愚蠢,可以通过将固定字符串显示在右边来改进。但这不是我的问题:我想知道为什么我的regex-fu让我失望)
发布于 2016-03-08 12:03:10
点匹配任何字符(如果DOTALL模式关闭,则为换行符)。*和*?匹配0+字符,只是.*一次抓取所有内容,*?一步一步地完成,在重新尝试*?子subppatern之前检查匹配的后续子模式。在这里,您混淆了“贪婪”的含义:注意regex试图“以一切方式”找到匹配,当字符串中的某个位置发生不匹配时,它会重试量化的子模式,引擎会用贪婪的量词回溯,它会尽一切努力获取一个匹配。懒惰量词并不能保证您的模式不会因为量词定义中的额外?而过热。
因此,避免使用点匹配模式,如果您不是真正的意思,如果该模式是已知的。这里,可打印的ASCII模式是必需的-然后使用它,不依赖于点匹配。
@{{(?P<id>TAGS|[ -~]+?):(?:(?P<attr>DATADIR|TAGSFILE|RESULT_INT)|(?P<expr>[ -~]+?))}}@注意,[ -~]匹配任何可打印的ASCII字符。见http://www.catonmat.net/blog/my-favorite-regex/。
模式匹配:
@{{前导定界符(?P<id>TAGS|[ -~]+?) -匹配TAGS或1+可打印的ASCII字符的id组,但尽可能少,因为它也匹配: (您可以限制字符类的前瞻性以排除:或用[ -9;-~]替换以使模式更加优化,并使用这个量词消除? ): -文字:(?:(?P<attr>DATADIR|TAGSFILE|RESULT_INT)|(?P<expr>[ -~]+?)) --将DATADIR、TAGSFILE或RESULT_INT匹配为attr组,或匹配一个或多个可打印的ASCII (尽可能少),并将位置匹配为组"expr“。同样,它在这里很懒,因为[ -~]与}匹配。否则,您可以在这里使用脾气暴躁的象征:(?:(?!}}@)[ -~])+。请参阅演示}}@ -尾随分隔符发布于 2016-03-08 11:40:36
这里有一个看起来像你想做的事的正则表达式:
@{{(?:(?:(?P<id>[^:]*?):(?P<attr>DATADIR|TAGSFILE|RESULT_INT))|TAGS:(?P<expr>.*?))}}@MATCH 1
expr [8-37] `sTagsJob << "job||ID||source"`
MATCH 2
id [50-53] `job`
attr [54-61] `DATADIR`
MATCH 3
id [79-82] `job`
attr [83-90] `DATADIR`您的正则表达式中有一个错误阻止它匹配TAG部件(P<expr>.?))}}@中忘记了一个kleene星?),但这本身并不能解决匹配过多的问题,所以我在<id>之后将这个点更改为“非冒号”。
https://stackoverflow.com/questions/35866192
复制相似问题