表达式直到注释或行尾
虽然这个问题和这个讨论有点相似,但我觉得我在用正则表达式写代码的时候可能做错了什么。
我想要匹配一行中的所有内容,直到遇到注释符号(“#”)或者行的结束(如果没有注释的话)。
我现在用的正则表达式是:(.*)(#|$)
(.*)
= 所有内容
(#|$)
= 注释或者行的结束
代码如下:
OPTION = re.compile(r'(?P<value>.*)(#|$)')
file = open('file.txt')
lines = file.read()
for line in lines.split('\n'):
get_match = OPTION.match(line)
if get_match:
line_value = get_match.group('value')
print "Match= %s" % line_value
这个正则表达式可以工作,但它并没有去掉注释。如果文件中有一行像这样:
this is a line # and this is a comment
运行代码时,我仍然会得到整行内容。
我是不是在正则表达式中漏掉了什么值或信息,还是说我需要对代码进行修改?
4 个回答
1
@Can、@Benji 和 @ΤΖΩΤΖΙΟΥ 提供了三个很棒的解决方案,看看它们的匹配速度也是很有趣的(这就是 timeit
的用途——进行一些无意义的小测试,哈哈;)。比如:
$ python -mtimeit -s'import re; r=re.compile(r"([^#]*)(#.*)?"); s="this is a line # and this is a comment"' 'm=r.match(s); g=m.group(1)'
100000 loops, best of 3: 2.02 usec per loop
对比
$ python -mtimeit -s'import re; r=re.compile(r"^(.*?)(?:#|$)"); s="this is a line # and this is a comment"' 'm=r.match(s); g=m.group(1)'
100000 loops, best of 3: 4.19 usec per loop
对比
$ python -mtimeit -s'import re; r=re.compile(r"(.*?)(#|$)"); s="this is a line # and this is a comment"' 'm=r.match(s); g=m.group(1)'
100000 loops, best of 3: 4.37 usec per loop
最后的赢家是……几种模式的结合!-)
$ python -mtimeit -s'import re; r=re.compile(r"(.*?)(#.*)?"); s="this is a line # and this is a comment"' 'm=r.match(s); g=m.group(1)'
1000000 loops, best of 3: 1.73 usec per loop
声明:当然,如果这是一个真正的性能测试,速度确实很重要的话,应该用很多不同的、相关的值来测试 s
,而且测试的内容也要超出这种小测试等等。但我还是觉得 timeit
是个无穷无尽的乐趣来源!-)
3
这是一个正确的正则表达式,可以用来做类似的事情:
([^#]*)(#.*)?
另外,为什么不直接使用
file = open('file.txt')
for line in file:
7
这个 * 符号是贪婪的,也就是说它会尽可能多地匹配字符串,所以它把整行都匹配了,包括 # 后面的内容,一直到行的结尾。你只需要把 ".*" 改成 ".*?",这样就能正常工作了。
想了解更多信息,可以查看这个 正则表达式入门指南。