Python:不以#开头的行

时间:2015-12-07 09:03:17

标签: python regex

我有一个包含类似

的文件
  

#comment
  #comment
   不是评论

     

#comment
  #comment
   不是评论

我试图逐行读取文件,只捕获不以#开头的行。我的代码/正则表达式出了什么问题?

import re

def read_file():
    pattern = re.compile("^(?<!# ).*")

    with open('list') as f:
        for line in f:
            print pattern.findall(line)

原始代码捕获所有内容而非预期内容。

4 个答案:

答案 0 :(得分:11)

另一种简单的方法是仅检查您阅读的每一行的第一个char是否包含#字符:

def read_file():

    with open('list') as f:
        for line in f:
            if not line.lstrip().startswith('#'):
                print line

答案 1 :(得分:11)

Iron Fist显示了你应该这样做的方式;但是,如果你想知道你的正则表达式有什么问题,应该是这样的:

^[^#].*

说明:

  • ^ - 匹配行首。
  • [^#] - 匹配不是#的内容。 [^...]就是说你不匹配的东西(只需将...替换为你不想匹配的任何字符。例如,[^ABC123]将匹配一个不是A,B的字符,C,1,2或3.不要让表示行/字符串开头的^在这里混淆你。这两个^是完全无关的。
  • .* - 匹配零或更多其他内容。

修改

^(?<!# ).*不区分# commentnot a comment的原因是(?<!#)在当前位置之前检查文本。引擎在字符串开头之后的第一个符号之前查找#,并且由于字符串开头之前没有#,因此任何行都匹配.*子模式。要真正检查第一个符号是否为#,您只需使用^#.*正则表达式。或者,如果可以有前导空格^\s*#

答案 2 :(得分:4)

由于:

  

(?!# )否定 Lookahead - 断言无法匹配下面的正则表达式
  (?<!# )否定 Lookbehind - 断言无法匹配正则表达式#
  来自regex101

这意味着它只匹配#。所以我的意思是:

>>> re.search('foo(?!bar)', 'foobar')
>>> re.search('foo(?<!bar)', 'foobar')  # doesn't work
<_sre.SRE_Match object; span=(0, 3), match='foo'>


>>> re.search('(?<!bar)foo', 'barfoo')
>>> re.search('(?!bar)foo', 'barfoo')   # doesn't work
<_sre.SRE_Match object; span=(3, 6), match='foo'>

这是因为您使用了错误的令牌。所以答案很简单:

  

如果 (?!bar) 之后不想要某些字符串,请使用bar
  如果
(?<!bar) 之前不想要某些字符串,请使用bar

答案 3 :(得分:1)

在这种情况下使用match功能 - 因为它会在开头检查。

所以表达式为\s*[^#] - 为了理智,我使用\s来传递空格。

OP的代码将是 -

def read_file():
    pattern = re.compile("\s*[^#]")
    with open(r"C:\test.txt") as f:
        for line in f:
            if pattern.match(line):
                    print line
read_file()

编辑 -

有点解释为什么OP的模式不起作用 -

当您使用.时,除换行符外,它意味着全部。所以当你写^(?<!# ).*时,它意味着any字符(除了换行符,它包含#该死的!)之前没有# - 最终它变成任何字符串(除了换行符)以any字符开头。

参见 LIVE DEMO

解决方案:

尝试像negation

这样的^(?<!# )[^#]