2

我正在为 C 样式预处理器编写一个简单的文本抓取器。输入文本(示例):

#if 1 > 0
blah
#if defined MACRO1
blah blah blah
#if !defined MACRO2
blaaaah
#if      !   defined MACRO3
blah?

我想捕获每个#if [!] defined语句之后的文本。我需要从上述文本中得到的输出是:

MACRO1
MACRO2
MACRO3

此处需要捕获的行号是 3、5 和 7。请注意,第 7 行有空格和制表符。

我试图创建可以给我这个结果的表达式,但没有一个如此出色。我给出预期结果的表达是-

(?<=(?<=(?<=(?<=(?<=(?<=#if)[\s\t]+)!?)[\s\t]*)defined)[\s\t]+).*

使用的选项是:Multiline + IgnoreCase

但我确信这并不优雅和简洁。有人可以建议更好的表达方式吗?

PS - 我正在使用Expresso来测试表达式。

4

4 回答 4

1

这个正则表达式呢?

#if[\s\t]+[!]?[\s\t]*defined[\s\t]*(.*)

在反向引用中,您会得到 MACRO1/MACRO2/MACRO3。

于 2011-04-07T18:36:32.310 回答
1

这应该可以工作,因为 s 包含您的问题中的输入以及换行符等

foreach(var match in Regex.Matches(s, @"(?<=#if\s*!?\s*defined\s*)(?<macro_name>\w+)")) {
  Console.WriteLine(match);
}

将找到 MACRO01、MACRO02 和 MACRO03 作为 3 个捕获

于 2011-04-07T19:35:05.517 回答
0

艾纳扬

我知道您需要获取通用 c 源代码文本流中的所有“#if defined”和“#if !defined”预处理器指令的宏引用名称......

我可以建议你简单的正则表达式

^#if\s*!?\s*defined\s*(\w*).*$

前一个正则表达式只定义了一个捕获组 (\w*),以便仅获取宏名称。

捕获组将填充所有出现的宏名称。

*PS:正则表达式必须使用多行+忽略大小写选项执行。我用 RegExr 工具测试了那个http://gskinner.com/blog/archives/2008/03/regexr_free_onl.html *

于 2011-04-07T18:49:50.030 回答
0

这行得通吗,

^#if(?:[ \t]*!)?[ \t]*defined[ \t]*(.*?)$

没有多行选项?

于 2011-04-07T19:10:56.863 回答