2

我在为当前的测试用例获取正确的正则表达式时遇到了麻烦。

示例测试用例:

#include <stdio.h>
#include <stdlib.h>
#include <foo_file.h>

int myint = atoi(foostring1);

float myfloat = atof(foostring2);

int myint2 = atoi(foostring3);

用例:

  1. 字符串包含 atof 和
  2. 字符串不包含字符串 stdlib.h
  3. 组无关紧要。我只想知道字符串是否存在。

使用正则表达式

(?=^#include <stdlib.h>).*atof

我可以找到该文件是否包含 stdlib 标头和 atof。效果很好。但是我似乎无法得到负面的期待正则表达式

(?!(?=.*^#include <stdlib.h>)).*(atoi)

我已经尝试了上述正则表达式行的许多小时的不同迭代,但无法使其正常工作。

假设我正在使用的 IDE 的正则表达式引擎允许匹配新/行返回字符,并允许我选择我想要使用的正则表达式解析器/引擎(但我通常使用 perl 的)

4

1 回答 1

2

问题是您的匹配可以从字符串中的任何位置开始。特别是, 您#include stdlib.h. 然后,前瞻不再找到stdlib.h,匹配成功。无论多行模式如何,许多正则表达式风格都提供\A匹配字符串的开头(并且仅在那里)。因此,要强制先行查看整个字符串,请执行以下操作:

\A(?!.*^#include <stdlib[.]h>).*(atoi)

请注意,您不需要在其中嵌套另一个前瞻。

另请注意,即使#includeafter atoi也会失败。如果不希望这样,基本上有两种解决方案:

如果你可以选择 .NET 的正则表达式风格,你可以把它变成一个lookbehind:

(?<!^#include <stdlib[.]h>.*)atoi

其他风格不允许这样做,因为它们要求后视具有固定的宽度。

在这些情况下,您必须在字符串开头和 之间的每个位置检查atoi它是否不标记 的开头include

\A(?:(?!^#include <stdlib[.]h>).)*(atoi)

因此,该(?:...)组将任意字符与该特定位置的前瞻组合在一起,然后重复整个过程。

于 2013-08-13T19:32:05.250 回答