2

谁能指出我从 C 源代码中剥离字符串的程序?例子

#include <stdio.h>
static const char *place = "world";
char * multiline_str = "one \
two \
three\n";
int main(int argc, char *argv[])
{
        printf("Hello %s\n", place);
        printf("The previous line says \"Hello %s\"\n", place);
        return 0;
}

变成

#include <stdio.h>
static const char *place = ;
char * multiline_str = ;
int main(int argc, char *argv[])
{
        printf(, place);
        printf(, place);
        return 0;
}

我正在寻找的是一个非常类似于stripcmt的程序 ,只是我想删除字符串而不是注释。

我正在寻找一个已经开发的程序而不仅仅是一些方便的正则表达式的原因是因为当您开始考虑所有极端情况(字符串中的引号、多行字符串等)时,事情通常会开始(远)比它复杂首先出现。REs 可以实现的目标是有限的,我怀疑这项任务是不可能的。如果您确实认为您有一个非常强大的正则表达式,请随时提交,但请不要提出天真sed 's/"[^"]*"//g'的建议。

(不需要对评论中的(可能是未结束的)字符串进行特殊处理,这些将首先被删除)

支持带有嵌入换行符的多行字符串并不重要(不合法的 C 语言),但必须支持跨越多行以 \ 结尾的字符串。

这与其他一些 问题几乎相同,但我没有找到任何工具的参考。

4

4 回答 4

5

C(和大多数其他编程语言)中的所有标记都是“常规的”。也就是说,它们可以通过正则表达式匹配。

C 字符串的正则表达式:

"([^"\\\n]|\\(['"?\\abfnrtv]|[0-7]{1,3}|x[0-9a-fA-F]+))*"

正则表达式并不难理解。基本上,字符串文字是一对围绕以下内容的双引号:

  • 非特殊(非引号/反斜杠/换行符)字符
  • 转义,以反斜杠开头,然后由以下之一组成:
    • 一个简单的转义字符
    • 1 到 3 个八进制数字
    • x 和 1 个或多个十六进制数字

这是基于 C89/C90 规范的 6.1.4 和 6.1.3.4 部分。如果 C99 中出现了其他问题,这将无法解决,但这应该不难解决。

这是一个用于过滤 C 源文件并删除字符串文字的 python 脚本:

import re, sys
regex = re.compile(r'''"([^"\\\n]|\\(['"?\\abfnrtv]|[0-7]{1,3}|x[0-9a-fA-F]+))*"''')
for line in sys.stdin:
  print regex.sub('', line.rstrip('\n'))

编辑:

在我发布上述内容后,我突然想到,虽然所有 C 标记都是常规的,但如果不标记所有内容,我们就有可能遇到麻烦。特别是,如果双引号出现在应该是另一个标记的地方,我们可以被引导到花园小路上。您提到评论已经被剥离,所以我们真正需要担心的唯一另一件事是字符文字(尽管我将使用的方法也可以轻松扩展以处理评论)。这是一个处理字符文字的更强大的脚本:

import re, sys
str_re = r'''"([^"\\\n]|\\(['"?\\abfnrtv]|[0-7]{1,3}|x[0-9a-fA-F]+))*"'''
chr_re = r"""'([^'\\\n]|\\(['"?\\abfnrtv]|[0-7]{1,3}|x[0-9a-fA-F]+))'"""

regex = re.compile('|'.join([str_re, chr_re]))

def repl(m):
  m = m.group(0)
  if m.startswith("'"):
    return m
  else:
    return ''
for line in sys.stdin:
  print regex.sub(repl, line.rstrip('\n'))

本质上,我们正在寻找字符串和字符文字标记,然后单独留下 char 文字,但去掉字符串文字。char 文字正则表达式与字符串文字非常相似。

于 2009-08-18T15:32:25.313 回答
4

您可以将源代码下载到 StripCmt (.tar.gz - 5kB)。它非常小,并且不应该太难适应条带化字符串(它是在 GPL 下发布的)。

您可能还想研究 C 字符串的官方词汇语言规则。我很快就发现了这一点,但它可能不是确定的。它将一个字符串定义为:

stringcon ::= "{ch}", where ch denotes any printable ASCII character (as specified by isprint()) other than " (double quotes) and the newline character.
于 2009-08-18T15:02:35.610 回答
0

在红宝石中:

#!/usr/bin/ruby
f=open(ARGV[0],"r")
s=f.read
puts(s.gsub(/"(\\(.|\n)|[^\\"\n])*"/,""))
f.close

打印到标准输出

于 2009-08-18T16:28:13.173 回答
0

在 Python 中使用 pyparsing:

from pyparsing import dblQuotedString

source = open(filename).read()
dblQuotedString.setParseAction(lambda : "")
print dblQuotedString.transformString(source)

也打印到标准输出。

于 2009-09-04T16:47:48.430 回答