【问题标题】:Regular expression to extract header name from c file从c文件中提取标题名称的正则表达式
【发布时间】:2017-05-08 23:11:00
【问题描述】:

如何从包含这样的 c 文件中提取标题?

#include <tema4header9.h>
#include    <tema4header3.h>
#include   <stdio.h>
#include        <longnametest/newheader.h>
#include <net/header.h>
#include  "last-test-Zhy3/DrRuheader.h"
#include <last-test-8fF7/a5xyheader.h>

我尝试使用:

sed -n -e 's/#include[ \t]*[&lt;"]\([^ \/&lt;"]*\/[^ \/]*\)\.h["&gt;]/\1\.h/p'

但它只适用于子目录中的那些。如果我输入:

sed -n -e 's/#include[ \t]*[&lt;"]\(([^ \/&lt;"]*\/)+[^ \/]*\)\.h["&gt;]/\1\.h/p'

sed -n -e 's/#include[ \t]*[&lt;"]\(([^ \/&lt;"]*\/)*[^ \/]*\)\.h["&gt;]/\1\.h/p'

该命令不再起作用。输出文件应如下所示:

tema4header9.h
tema4header3.
stdio.h
longnametest/newheader.h
net/header.h
last-test-Zhy3/DrRuheader.h
last-test-8fF7/a5xyheader.h

【问题讨论】:

  • 您的预期输出是什么? tema4header9.h,等等……?

标签: regex bash sed grep


【解决方案1】:

如上:

sed -n 's/\s*#\s*include\s*[<"]\(.\+.h\)[>"]/\1/p' input_file

但它更精确,例如, input_file 的内容是:

 # include <stdio.h>
       #        include<stdlib.h>
    #    include    <time.h>
 #define LEN 8
 #define OPT 2
 #include <pthread.h>
 # include "mysql.h"
 #include "paths.h"

它仍然可以正确打印:

stdio.h
stdlib.h
time.h
pthread.h
mysql.h
paths.h

【讨论】:

    【解决方案2】:

    试试:

    awk '{match($0,/[<"].*[>"]/);print substr($0,RSTART+1,RLENGTH-2)}' Input_file
    

    【讨论】:

      【解决方案3】:

      grep 解决方案:这是使用 perl 正则表达式并在以 #include 开头的行上打印 "&lt;"'"' 之间的任何内容。

      grep -oP '^#include.*(<|")\K.*(?=>|")' headers
      tema4header9.h
      tema4header3.h
      stdio.h
      longnametest/newheader.h
      net/header.h
      last-test-Zhy3/DrRuheader.h
      last-test-8fF7/a5xyheader.h
      

      如果你对awk没问题:

      awk '/#include/{gsub(/<|>|"/,"",$2);print $2}' headers
      tema4header9.h
      tema4header3.h
      stdio.h
      longnametest/newheader.h
      net/header.h
      last-test-Zhy3/DrRuheader.h
      last-test-8fF7/a5xyheader.h
      

      【讨论】:

      • 只要'(?&lt;="|\&lt;).*(?="|\&gt;)' 就足够了grep
      • @Inian 可能会从file.c 中不需要的行中提取一些数据,例如cout &lt;&lt; "hey there" &lt;&lt; "x&gt;y" &lt;&lt;endl;,因此添加#include 作为安全措施。由 OP 来判断风险。
      • 我的意思是在引号和&lt; 中单独提取部分,同意前面的部分是必要的。
      • 谁能告诉我如何为 C++ regex_search 编写上述 grep 之类的正则表达式?
      • 警告:这些模式不会捕获所有#include。在 C/C++ 中,# 周围允许有空格和制表符。例如。 # include &lt;header.h&gt;。正确:grep -oE '^[ \t]*#[ \t]*include[ \t]*(&lt;[^&lt;]*&gt;|"[^"]*")' headers
      【解决方案4】:

      这应该可行:

      sed -nr 's/#include\s+[<"]([^>"]+)[>"].*/\1/p'
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-07-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-02-19
        相关资源
        最近更新 更多