Lex:匹配忽略空间

时间:2017-04-18 18:43:20

标签: regex lex

我有识别十六进制数的工作, 我的问题是如何忽略空间,但之前不允许任何角色 像这样:

0x7f6e ---->match,and print"0x7f6e"
    0X2146 ---->match,and print"0X21467"
acns0x8972 ----> not match

我现在的工作:

hex     \s*0[X|x][0-9a-fA-f]{1,4}(^.)*(\n)

{hex}   { ECHO;}
.|\n    {}

并打印:

0x7f6e
    0X2146 

如何在没有空间的情况下打印它? 像这样:

0x7f6e
0X2146 

1 个答案:

答案 0 :(得分:0)

我有一个应该按照你的期望做的工作版本:

%{
#include <ctype.h>
#include <stdio.h>
%}

%%

^[ \t]*0[Xx][0-9a-fA-f]{1,4}(.*)$ {
  /* skip spaces at begin of line */
  const char *bol = yytext;
  while (isspace((unsigned char)*bol)) ++bol;
  /* echo rest of line */
  puts(bol);
}

.|\n { }

%%

int main(int argc, char **argv) { return yylex(); }

int yywrap() { return 1; }

注意:

  1. \s似乎不受支持(至少在我的flex版本2.6.3中)。我用[ \t]替换了它。顺便说一句。 \s通常也与回车,换行符,换页符相匹配,而不是我的意图。

  2. (^.)*替换为(.*)。 (我不明白原来的意图。错误?)

  3. 我在第一个模式的开头添加了^,以便将模式附加到行的开头。

  4. 我用\n替换了十六行末尾的$puts()函数为输出添加换行符。 (换行符总是与第二条规则匹配,因此被跳过。)

  5. 我将ECHO;替换为一些C代码,以(1)删除行开头的空格,(第二个)将行的其余部分输出到标准输出通道。

  6. 在Windows 10(64位)上的cygwin中编译和测试:

    $ flex --version
    flex 2.6.3
    
    $ flex -o test-hex.c test-hex.l ; gcc -o test-hex test-hex.c
    
    $ echo "
    0x7f6e                                              
        0X2146
    acns0x8972
    " | ./test-hex
    0x7f6e
    0X2146
    
    $
    

    注意:我使用echo通过管道将您的示例数据提供给test-hex的标准输入渠道。