Lyn*_*ite 25 python regex string
我正在编写一个程序来自动编写一些C代码,(我正在编写将字符串解析为具有相同名称的枚举)C对字符串的处理并不是那么好.所以有些人一直在唠叨我试试python.
我创建了一个应该删除C风格/* COMMENT */
和//COMMENT
字符串的函数:这是代码:
def removeComments(string):
re.sub(re.compile("/\*.*?\*/",re.DOTALL ) ,"" ,string) # remove all occurance streamed comments (/*COMMENT */) from string
re.sub(re.compile("//.*?\n" ) ,"" ,string) # remove all occurance singleline comments (//COMMENT\n ) from string
Run Code Online (Sandbox Code Playgroud)
所以我尝试了这个代码.
str="/* spam * spam */ eggs"
removeComments(str)
print str
Run Code Online (Sandbox Code Playgroud)
它显然没有做任何事情.
关于我做错了什么的任何建议?
有一种说法,我听过几次:
如果您遇到问题而尝试使用Regex解决问题,最终会遇到两个问题.
编辑:回顾这几年后.(经过更多的解析经验)
我认为正则表达式可能是正确的解决方案.而这里使用的简单正则表达"足够好".我可能没有在这个问题上强调这一点.这是针对单个特定文件的.那没有棘手的情况.我认为保持文件解析对于正则表达式而言要简单得多,而不是将正则表达式复杂化为不可读的符号汤.
Onu*_*rım 34
已经给出了许多答案但是;
怎么样"//comment-like strings inside quotes"
?
OP正在询问如何使用正则表达式来做到这一点; 所以:
def remove_comments(string):
pattern = r"(\".*?\"|\'.*?\')|(/\*.*?\*/|//[^\r\n]*$)"
# first group captures quoted strings (double or single)
# second group captures comments (//single-line or /* multi-line */)
regex = re.compile(pattern, re.MULTILINE|re.DOTALL)
def _replacer(match):
# if the 2nd group (capturing comments) is not None,
# it means we have captured a non-quoted (real) comment string.
if match.group(2) is not None:
return "" # so we will return empty to remove the comment
else: # otherwise, we will return the 1st group
return match.group(1) # captured quoted-string
return regex.sub(_replacer, string)
Run Code Online (Sandbox Code Playgroud)
这将删除:
/* multi-line comments */
// single-line comments
不会删除:
String var1 = "this is /* not a comment. */";
char *var2 = "this is // not a comment, either.";
url = 'http://not.comment.com';
注意:这也适用于Javascript源代码.
msa*_*ers 29
re.sub
返回一个字符串,因此将代码更改为以下内容将得到结果:
def removeComments(string):
string = re.sub(re.compile("/\*.*?\*/",re.DOTALL ) ,"" ,string) # remove all occurrences streamed comments (/*COMMENT */) from string
string = re.sub(re.compile("//.*?\n" ) ,"" ,string) # remove all occurrence single-line comments (//COMMENT\n ) from string
return string
Run Code Online (Sandbox Code Playgroud)
jat*_*ism 16
我建议使用像SimpleParse或PyParsing这样的REAL解析器.SimpleParse要求您实际知道EBNF,但速度非常快.PyParsing有类似EBNF的语法,但它适用于Python,并且可以轻松构建功能强大的解析器.
编辑:
以下是在此上下文中使用PyParsing是多么容易的示例:
>>> test = '/* spam * spam */ eggs'
>>> import pyparsing
>>> comment = pyparsing.nestedExpr("/*", "*/").suppress()
>>> print comment.transformString(test)
' eggs'
Run Code Online (Sandbox Code Playgroud)
以下是使用单行和多行注释的更复杂示例.
之前:
/*
* multiline comments
* abc 2323jklj
* this is the worst C code ever!!
*/
void
do_stuff ( int shoe, short foot ) {
/* this is a comment
* multiline again!
*/
exciting_function(whee);
} /* extraneous comment */
Run Code Online (Sandbox Code Playgroud)
后:
>>> print comment.transformString(code)
void
do_stuff ( int shoe, short foot ) {
exciting_function(whee);
}
Run Code Online (Sandbox Code Playgroud)
它会在删除评论的地方留下额外的换行符,但这可以解决.
小智 8
在 Jathanism 之后,找到了另一个 pyparsing 解决方案。
import pyparsing
test = """
/* Code my code
xx to remove comments in C++
or C or python */
include <iostream> // Some comment
int main (){
cout << "hello world" << std::endl; // comment
}
"""
commentFilter = pyparsing.cppStyleComment.suppress()
# To filter python style comment, use
# commentFilter = pyparsing.pythonStyleComment.suppress()
# To filter C style comment, use
# commentFilter = pyparsing.cStyleComment.suppress()
newtest = commentFilter.transformString(test)
print(newest)
Run Code Online (Sandbox Code Playgroud)
产生以下输出:
include <iostream>
int main (){
cout << "hello world" << std::endl;
}
Run Code Online (Sandbox Code Playgroud)
还可以使用pythonStyleComment、javaStyleComment、cppStyleComment。发现它非常有用。
归档时间: |
|
查看次数: |
35816 次 |
最近记录: |