正则表达式匹配C #include文件

时间:2009-09-14 06:47:11

标签: regex

我需要一些帮助来尝试将C包含文件与完整路径匹配,如下所示:

#include <stdio.h>  -> stdio.h
#include "monkey/chicken.h" -> monkey/chicken.h

到目前为止,我(改编自我发现的另一个表达式):

^\s*\#include\s+(["'<])([^"'<>/\|\b]+)*([">])

但是,我有点卡在这一点 - 它在第二种情况下不匹配,我不确定如何返回匹配的结果,例如文件路径返回到regcomp()。

BTW我看过regexplib.com,但找不到合适的东西。

编辑:是的我是一个完全正则表达的新手,使用POSIX正则表达式与regmatch_t和朋友...

6 个答案:

答案 0 :(得分:7)

这是我写的:

#include ((<[^>]+>)|("[^"]+"))

适合吗?

答案 1 :(得分:5)

这会带来更好的结果:

^\s*\#include\s+["<]([^">]+)*[">]

然后,您希望在获得匹配时查看第一个捕获组。

你没有说你正在使用什么语言,你提到的因素regcomp()让我相信你在C中使用POSIX正则表达式库。如果这是正确的,那么你想使用regexec函数和使用nmatch和pmatch参数获取第一个捕获组。

答案 2 :(得分:2)

你可以试试这个正则表达式:

(^\s*\#\s*include\s*<([^<>]+)>)|(^\s*\#\s*include\s*"([^"]+)")

我更喜欢为#include <>
#include ""

分别使用正则表达式

答案 3 :(得分:2)

如果您想要更精确的解决方案,也允许在包含文件之前进行注释,例如

  /* ops, a comment */ /* oh, another comment */   #include  "new_header1.h" /* let's try another with an #include "old_header.h" */

是:

^(?:\s*|\s*\/\*.*?\*\/)\s*#include\s*(?:(?:<)(?<PATH>.*?)(?:>)|(?:")(?<PATH>.*?)(?:"))

答案 4 :(得分:1)

测试不是特别好,但它符合您的两种情况:

^\s*#include\s+(<([^"'<>|\b]+)>|"([^"'<>|\b]+)")

唯一的问题是由于&lt;和&gt;事情,结果可能是在捕获组2或3中,所以你应该检查2是否为空,然后使用3 ...优于其他一些答案的优点是它不会匹配......这样:#include“ bad.h&gt;或者:#include&lt; bad&lt;&lt; h&gt;

以下是如何使用(wrap)regcomp&amp; amp的示例朋友:

 static bool regexMatch(const std::string& sRegEx, const std::string& sSubject, std::vector<std::string> *vCaptureGroups)
 {
  regex_t re;
  int flags = REG_EXTENDED | REG_ICASE;
  int status;

  if(!vCaptureGroups) flags |= REG_NOSUB;

  if(regcomp(&re, sRegEx.c_str(), flags) != 0)
  {
   return false;
  }

  if(vCaptureGroups)
  {
   int mlen = re.re_nsub + 1;
   regmatch_t *rawMatches = new regmatch_t[mlen];

   status = regexec(&re, sSubject.c_str(), mlen, rawMatches, 0);

   vCaptureGroups->clear();
   vCaptureGroups->reserve(mlen);

   if(status == 0)
   {
    for(size_t i = 0; i < mlen; i++)
    {
     vCaptureGroups->push_back(sSubject.substr(rawMatches[i].rm_so, rawMatches[i].rm_eo - rawMatches[i].rm_so - 1));
    }
   }

   delete[] rawMatches;
  }
  else
  {
   status = regexec(&re, sSubject.c_str(), 0, NULL, 0);
  }

  regfree(&re);

  return (status == 0);
 }

答案 5 :(得分:0)

这对我有用:

'\#include\s*(<([^"<>|\b]+)>|"([^"<>|\b]+)")'