Lex(词法分析器)中正则表达式的大问题

时间:2010-03-26 23:35:43

标签: c regex lex lexical-analysis

我有一些这样的内容:

    author = "Marjan Mernik  and Viljem Zumer",
    title = "Implementation of multiple attribute grammar inheritance in the tool LISA",
    year = 1999

    author = "Manfred Broy and Martin Wirsing",
    title = "Generalized
             Heterogeneous Algebras and
             Partial Interpretations",
    year = 1983

    author = "Ikuo Nakata and Masataka Sassa",
    title = "L-Attributed LL(1)-Grammars are
             LR-Attributed",
    journal = "Information Processing Letters"

我需要在 title 的双引号之间捕捉所有内容。我的第一次尝试是这样的:

^(" "|\t)+"title"" "*=" "*"\"".+"\","

第一个例子,但不是其他两个。另一个有多条线,这就是问题所在。我想改变某个地方有\n的东西以允许多行,如下所示:

^(" "|\t)+"title"" "*=" "*"\""(.|\n)+"\","

但是这没有用,相反,它会捕获一切

比我说的,“我想要的是双引号,如果我找到所有内容,直到找到另一个"后跟,怎么办?这样我就可以知道我是否在最后标题与否,无论行数如何:

^(" "|\t)+"title"" "*=" "*"\""[^"\""]+","

但这有另一个问题......上面的例子没有它,但双引号符号(")可以在 title 声明之间。例如:

title = "aaaaaaa \"X bbbbbb",

是的,它始终以反斜杠(\)开头。

修复此正则表达式的任何建议?

2 个答案:

答案 0 :(得分:2)

用双引号匹配字符串的经典正则表达式是:

\"([^\"]|\\.)*\"

在你的情况下,你会想要这样的东西:

"title"\ *=\ *\"([^\"]|\\.)*\"
PS:恕我直言,你在你的正则表达中引用了太多的引号,这很难读。

答案 1 :(得分:0)

您可以使用开始条件来简化每个单独的模式,例如:

%x title
%%
"title"\ *=\ *\"  { /* mark title start */
  BEGIN(title);
  fputs("found title = <|", yyout);
}

<title>[^"\\]* { /* process title part, use ([^\"]|\\.)* to grab all at once */
  ECHO;
}

<title>\\. { /* process escapes inside title */
  char c = *(yytext + 1);
  fputc(c, yyout); /* double escaped characters */
  fputc(c, yyout);
}

<title>\" { /* mark end of title */
  fputs("|>", yyout);
  BEGIN(0); /* continue as usual */
}

制作可执行文件:

$ flex parse_ini.y
$ gcc -o parse_ini lex.yy.c -lfl

运行它:

$ ./parse_ini < input.txt 

input.txt的位置:

author = "Marjan\" Mernik  and Viljem Zumer",
title = "Imp\"lementation of multiple...",
year = 1999

输出:

author = "Marjan\" Mernik  and Viljem Zumer",
found title = <|Imp""lementation of multiple...|>,
year = 1999

它取代了标题'"' '<|''|>'. Also'\''`被标题内的'“”替换。