Flex正则表达式识别AWK正则表达式

时间:2012-09-25 03:17:35

标签: c regex awk lex

我正在整理我的flex扫描仪的最后一个模式来解析AWK源代码。

我无法弄清楚如何匹配AWK源代码中使用的正则表达式,如下所示:

{if ($0 ~ /^\/\// ){ #Match for "//" (Comment)

或更简单:

else if ($0 ~ /^Department/){

其中AWK正则表达式封装在“/ /”中。

到目前为止,我尝试过的所有Flex模式都与我的整个输入文件相匹配。我试过改变正则表达式的优先级并且没有找到运气。非常感谢帮助!!

2 个答案:

答案 0 :(得分:2)

regexing regexen必须是某个地方的模因。无论如何,让我们试一试。

gawk正则表达式包括:

  • /

  • 任意数量的正则表达式组件

  • /

正则表达式组件(简化形式 - 注释1)是以下之一:

  • /[\

  • 以外的任何字符
  • 一个\后面跟着任何一个字符(不过我们现在还没有进入换行符。

  • 一个角色类(见下文)

到此为止,这很容易。现在是有趣的部分。

字符类是:

  • [[^[][^](注2)

  • 任意数量的字符类组件

  • ]

一个字符类组件(理论上,但请参见下面的gawk bug)以下之一:

  • ]\以外的任何单个字符(注3)

  • \后跟任何单个字符

  • 字符类

  • 整理课程

字符类是:(注5)

  • [:

  • 一个有效的类名,afaik总是一系列字母字符,但它可能更安全,不做假设。

  • :]

归类类主要是未实现但部分解析。你可能会忽略它们,因为看起来gawk还没有把它们弄好(注4)。但是为了它的价值:

  • [.

  • 一些多字符校对字符,例如' ij'在荷兰语中(我认为)。

  • .]

或等价类:

  • [=

  • 某个角色,或者也可能是多角色整理角色

  • =]

重要的一点是[/] 终止正则表达式。你不需要写[\/]。 (你不需要做任何事情来实现它。我只是提到它。)。


注1:

实际上,\和角色类的解释,当我们到达它们时,要复杂得多。我只是为lexing描述了足够的内容。如果你真的想把regexen解析成它们的点点滴滴,那就太烦人了。

例如,您可以使用\ddd\xHH(例如\203\x4F)指定任意八位字节。但是,我们不需要关心,因为逃脱序列中的任何内容都不是特别的,所以对于lexing目的来说它并不重要;我们得到了lexeme的正确结束。类似的,我没有在字符类中描述字符范围和-的特殊规则,也不担心正则表达式元字符(){}?*+.,因为它们不会进入进入乐兴。您必须担心[],因为它可以隐式隐藏/以终止正则表达式。 (我曾经写过一个正则表达式解析器,它可以让你隐藏/在括号内的表达式中,我认为这很酷 - 它可以减少很多关于这里的噪音(\/) - 但没有其他人似乎认为这是一个好主意。)


注2:

尽管gawk在字符类中出现\错误(参见下面的注释3),但它并不要求您使用它们,因此您仍然可以使用Posix行为。 Posix行为是]不会终止字符类,如果它是字符类中的第一个字符,可能跟随否定^。解决这个问题的最简单方法是让字符类从四个可能的序列中的任何一个开始,总结如下:

\[^?]?


注3:

gawk与Posix ERE(扩展正则表达式)的不同之处在于它将字符类中的\解释为转义字符。 Posix要求\在角色类中失去其特殊含义。我发现gawk这样做很烦人(许多其他的正则表达式库也是如此,同样令人讨厌。)gawk信息手册说Posix要求它执行此操作时特别恼人,因为它实际上需要反向。但那只是我。无论如何,gawk:

/[\]/]/

是一个与]/匹配的正则表达式。在Posix中,剥离封闭的/,它将是一个正则表达式,匹配\后跟/后跟]。 (gawk和Posix都要求]在没有被视为字符类终止符时不是特殊的。)


注4:

在我的机器上安装的gawk版本中存在一个错误,其中正则表达式解析器在整理类结束时感到困惑。因此它认为正则表达式在第一秒/中终止:

/[[.a.]/]/

虽然它是正确的:

/[[:alpha:]/]/

当然,先把斜杠放在首位:

/[/[:alpha:]]/


注5:

字符类和整理类和朋友解析有点棘手,因为它们有两个字符的终止符。 "写一个正则表达式来识别C / * * / comments"曾经是一个标准的面试问题,但我想它不再是。无论如何,这是一个解决方案(对于[:...:],但只是替代:如果你想要另一个标点符号):

[[]:([^:]|:*[^]:])*:+[]]   // Yes, I know it's unreadable. Stare at it a while.

答案 1 :(得分:0)

正则表达式无需“/.../”即可查看示例:

print all numbers starting with 7 from 1-100:

kent$  seq 100|awk '{if($0~"7[0-9]")print}'
70
71
72
73
74
75
76
77
78
79

kent$  awk --version
GNU Awk 3.1.6