【问题标题】:How can I use lookbehind assertions in lex?如何在 lex 中使用后向断言?
【发布时间】:2011-08-02 16:08:36
【问题描述】:

我需要 lex (flex 2.5.35) 中的积极后向断言。在调查了文档之后,我没有看到直接的方法来做到这一点。它有一些类似于前瞻断言(r/s 语法)的东西,但不是后瞻断言。达到相同效果的最佳方法是什么?

这是一个示例:假设我的扫描仪规范文件中有以下规则:

a         printf("matched a ");
b         printf("matched b ");
c         printf("matched c ");
d         printf("matched d ");

如何匹配 'b' 后面的 'd' 和 'b' 本身,这样在输入 'abd' 时我会得到:

matched a matched b matched d following b

但是对于字符串'acd'

matched a matched c matched d

规则:

bd        printf("matched d following b ");

显然不起作用,因为它消耗 b;对于“abd”,它输出:

matched a matched d following b

如果我有 pcre lookbehinds 我可以写:

(?<=b)d   printf("matched d following b ");

一切都会好起来的,但 lex 不支持这个。

【问题讨论】:

    标签: regex lex flex-lexer


    【解决方案1】:

    您可能可以使用start conditions 实现您想要的,但代价是更复杂的扫描仪。开始条件允许您根据之前匹配的内容有条件地启用规则。这是一个例子:

    %x matched_b
    %%
    <INITIAL,matched_b>{
        a       { printf("matched a\n"); BEGIN(INITIAL); }
        b       { printf("matched b\n"); BEGIN(matched_b); }
        c       { printf("matched c\n"); BEGIN(INITIAL); }
    }
    
    d       printf("matched d\n");
    <matched_b>d    { printf("matched d following b\n"); BEGIN(INITIAL); }
    

    有了这个扫描仪,我得到:

    $ echo abcd | ./5615080
    matched a
    matched b
    matched c
    matched d
    
    $ echo abdd | ./5615080
    matched a
    matched b
    matched d following b
    matched d
    

    【讨论】:

    • 嗯。这看起来很复杂,但我想没有其他办法。感谢您的帮助。
    【解决方案2】:

    如果您只有一个前瞻断言,我可以想到两种可能性。

    1. 反转您的字符串,并搜索您的反转模式。在你的模式之前的通常情况现在已经领先了。

    2. 我认为对于某些正则表达式风格,可以从右到左解析,也许这可以帮助您与您的前瞻一起。

    否则你应该发布一些示例字符串和你期望的结果,也许它可以在不使用后面断言的情况下实现。

    【讨论】:

      【解决方案3】:

      对于 pcre,语法如下:

      (?&lt;= ... ) 表示正面
      (?&lt;! ... ) 负面

      而pcre需要固定长度的look behinds(正或负)。

      如果 lex 有它们,它可能是这种形式。

      【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-03-16
      • 2020-03-04
      • 1970-01-01
      • 1970-01-01
      • 2019-10-22
      相关资源
      最近更新 更多