Lex:匹配忽略 space

Lex: match ignore space

我有一个识别十六进制数的工作, 我的问题是如何忽略 space,但不允许之前的任何字符。
像这样:

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 

没有space我怎么打印? 像这样:

0x7f6e
0X2146 

我得到了一个工作版本,它应该可以满足您的期望:

%{
#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 似乎不受支持(至少在我的 2.6.3 版本的 flex 中)。我用 [ \t] 代替了它。顺便提一句。 \s 通常也匹配回车符 return、换行符、换页符,这在我的例子中不是预期的。

  2. (^.)* 替换为 (.*)。 (没看懂原作者的用意,搞错了吗?)

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

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

  5. 我用一些 C 代码替换了 ECHO; 以(1st)删除行首的空格,(2nd)将行的其余部分输出到标准输出通道。

在 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 的标准输入通道。