2012-09-25 110 views
1

我正在放置我的柔性扫描程序来解析AWK源代码的最后一个模式。Flex正则表达式来标识AWK正则表达式

我不能找出如何匹配在AWK源代码中使用的正则表达式,如下所示:

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

或更简单地说:

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

在AWK正则表达式被封装内“/ /”。

到目前为止我尝试过的所有Flex模式都与我的整个输入文件匹配。我试图改变正则表达式的优先顺序,并没有发现运气。帮助将不胜感激!

回答

2

regexing regexen必须是某处的模因。无论如何,让我们试试看吧。

了徒劳无功正则表达式包括:

  • /

  • 任何数目的正则表达式部件

  • /

甲正则表达式的组分(简化的形式 - 注1)是一个以下内容:

  • 任何字符比/[\

  • 一个\后跟任何单个字符等(我们不会进入换行符刚才,虽然。

  • 字符类(见下文)

到这里很容易。现在是有趣的部分。

字符类是:

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

  • 任何数量的字符类组件的

  • ]

字符类组分是(理论上,但是参见下文对于GAWK臭虫)执行以下操作之一:

  • 任何单个比]\其它字符(注3)

  • 一个\随后由任何单个字符

  • 字符类

  • 核对ç姑娘

字符类是:(注5)

  • [:

  • 有效的类名称,据我所知是永远的字母字符序列,但它也许更安全不做出假设。

  • :]

排序规则类主要是未实现的,但部分地解析。你可能会忽略它们,因为它看起来像gawk并没有让它们正确(注4)。但对于什么是价值:

  • [.

  • 一些多字符归类字符,像荷兰的语言环境 'IJ'(我认为)。

  • .]

或一个等价类:

  • [=

  • 一些字符,或者也许还多字符归类字符

  • =]

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


注1:

其实,\和字符类的旅游解说,当我们到他们,是一个复杂得多。我只是对它的描述足以说明这一点。如果你真的想把正则表达式解析成它们的零碎,那就更加恼人了。

例如,您可以使用\ddd\xHH(例如\203\x4F)指定任意八位位组。但是,我们不需要关心,因为转义序列中没有任何特殊的东西,所以为了汲取目的不重要;我们会得到这个词汇的最后一个结尾。相似之处,我并没有在字符类中描述字符范围和-的特殊规则,也根本不用担心正则表达式字符(){}?*+.,因为它们没有进入lexing。您不必担心[],因为它可以隐式地隐藏/终止正则表达式。 (我曾经写过一个正则表达式解析器,它可以让你在括号内隐藏/,我认为它很酷 - 它减少了很多关于这个噪音的噪音(\/) - 但似乎没有人认为这是一个好主意。)


注2:

虽然GAWK确实\错误的字符类中(见下面的注释3),它不需要你使用它们,所以你仍然可以使用POSIX的行为。 Posix的行为是]不会终止字符类,如果它是字符类中的第一个字符,可能跟在否定^之后。对付这种最简单的方法是让字符类开始与任何四种序列,它概括为:

\[^?]? 


注3:

GAWK从Posix的ERE的(扩展正则表达式的区别),因为它将字符类中的\解释为转义字符。 Posix要求\在角色类中失去其特殊含义。我发现它很烦人,gawk会这样做(所以很多其他正则表达式库也同样令人讨厌)。特别令人讨厌的是,gawk信息手册说Posix要求它做到这一点,但实际上它需要相反的结果。但那只是我。不管怎样,在GAWK:

/[\]/]/ 

是其或者]/匹配正则表达式。在Posix中,除去封闭的/ s,这将是一个正则表达式,它与\后跟/后跟]匹配。 (两个呆子和POSIX需要的时候它不被视为一个字符类终止该]不是特别的。)


注4:

有一个在安装我的机器在正则表达式的GAWK的版本中的错误解析器在整理类的最后变得困惑。因此,它认为正则表达式是由第一第二/在终止:

/[[.a.]/]/ 

,虽然它得到这一权利:

/[[:alpha:]/]/ 

,当然,把斜线第一总是工作:

/[/[:alpha:]]/ 


注5:

字符类和col因为他们有两个字符的终结符,因此分班和朋友分析有点棘手。 “写一个正则表达式来识别C/* * /注释”曾经是一个标准的面试问题,但我认为它不再是。总之,这里是一个解决方案(用于[:...:],但只是替补:对于其他标点符号,如果你愿意的话):

[[]:([^:]|:*[^]:])*:+[]] // Yes, I know it's unreadable. Stare at it a while. 
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