有人能指出我从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非常相似的程序 只是我想剥离字符串而不是评论。
我正在寻找已经开发的程序,而不仅仅是一些方便的正则表达式
因为当你开始考虑所有角落情况(字符串中的引号,多行字符串等)
事情通常比最初出现的事情(更复杂)更复杂。和
RE有什么限制可以实现,我怀疑这项任务是不可能的。
如果你认为你有一个极其强大的正则表达式,可以随意提交,但请不要像天真的sed 's/"[^"]*"//g'
那样建议。
(不需要在评论中对(可能是未结束的)字符串进行特殊处理,这些字符串将首先删除)
支持带有嵌入换行符的多行字符串并不重要(不合法C),但必须支持跨越以\结尾的多行的字符串。
答案 0 :(得分:5)
C(和大多数其他编程语言)中的所有令牌都是“常规”。也就是说,它们可以通过正则表达式进行匹配。
C字符串的正则表达式:
"([^"\\\n]|\\(['"?\\abfnrtv]|[0-7]{1,3}|x[0-9a-fA-F]+))*"
正则表达式并不难理解。基本上字符串文字是一对双引号围绕着一堆:
这是基于C89 / C90规范的第6.1.4和6.1.3.4节。如果在C99中有其他任何东西悄悄进入,这将无法理解,但这应该不难解决。
这是一个python脚本,用于过滤删除字符串文字的C源文件:
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字面正则表达式与字符串字面值非常相似。
答案 1 :(得分:4)
您可以下载source code to StripCmt(.tar.gz - 5kB)。它很小,并且不应该太难以适应条纹字符串(它是released under the GPL)。
您可能还想调查C字符串的官方词汇语言规则。我很快就找到了this,但它可能不是确定的。它将字符串定义为:
stringcon ::= "{ch}", where ch denotes any printable ASCII character (as specified by isprint()) other than " (double quotes) and the newline character.
答案 2 :(得分:0)
在红宝石中:
#!/usr/bin/ruby
f=open(ARGV[0],"r")
s=f.read
puts(s.gsub(/"(\\(.|\n)|[^\\"\n])*"/,""))
f.close
打印到标准输出
答案 3 :(得分:0)
在Python中使用pyparsing:
from pyparsing import dblQuotedString
source = open(filename).read()
dblQuotedString.setParseAction(lambda : "")
print dblQuotedString.transformString(source)
同时打印到stdout。