繁体   English   中英

使用python和正则表达式从文本文件中删除行

[英]Removing lines from a text file using python and regular expressions

我有一些文本文件,我想删除所有以星号(“ *”)开头的行。

虚构示例:

words
*remove me
words
words
*remove me 

我当前的代码失败。 如下所示:

import re

program = open(program_path, "r")
program_contents = program.readlines()
program.close() 

new_contents = []
pattern = r"[^*.]"
for line in program_contents:
    match = re.findall(pattern, line, re.DOTALL)
    if match.group(0):
        new_contents.append(re.sub(pattern, "", line, re.DOTALL))
    else:
        new_contents.append(line)

print new_contents

产生[“,'','','','',', ',',', ','','*',``]],这不是问题。

我非常了解python,但是我很想学习。 最后,我将其捆绑到一个函数中(现在,我只是想在ipython笔记本中弄清楚它)。

谢谢您的帮助!

不想使用[^...]负字符类; 您正在匹配除*.以外的所有字符. 现在的字符。

*是一个元字符,您想将其转义为\\* . “匹配任何字符”语法需要一个乘数来匹配多个。 不要在这里使用re.DOTALL 您正在逐行操作,但不想删除换行符。

无需先进行测试; 如果没有什么可替换的,则返回原始行。

pattern = r"^\*.*"
for line in program_contents:
    new_contents.append(re.sub(pattern, "", line))

演示:

>>> import re
>>> program_contents = '''\
... words
... *remove me
... words
... words
... *remove me 
... '''.splitlines(True)
>>> new_contents = []
>>> pattern = r"^\*.*"
>>> for line in program_contents:
...     new_contents.append(re.sub(pattern, "", line))
... 
>>> new_contents
['words\n', '\n', 'words\n', 'words\n', '\n']

您的正则表达式似乎不正确:

[^*.]

均值匹配不是^*. 在方括号表达式中时,第一个^之后的所有内容均视为文字字符。 这意味着您具有表达式. 与匹配。 字符,而不是通配符。

这就是为什么在以*开头的行中得到"*"原因,您要替换除*所有字符! 您还可以保留任何内容. 存在于原始字符串中。 由于其他行不包含*. ,其所有字符将被替换。

如果要匹配以*开头的行:

^\*.*

可能更容易的是这样的事情:

pat = re.compile("^[^*]")

for line in contents:
    if re.search(pat, line):
        new_contents.append(line)

此代码仅保留不以*开头的任何行。

在模式^[^*] ,第一个^匹配字符串的开头。 表达式[^*]匹配除*任何字符。 因此,此模式将匹配不是*的字符串的任何起始字符。

在使用正则表达式时要认真考虑是一个好技巧。 您是否只需要断言某个字符串,是否需要更改或删除字符串中的字符,是否需要匹配子字符串?

就python而言,您需要考虑每个函数所提供的功能以及需要使用的功能。 有时,例如在我的示例中,您只需要知道找到了一个匹配项即可。 有时您可能需要对比赛做些事情。

有时re.sub并不是最快或最好的方法。 当您只需要跳过该行时,为什么还要烦恼每一行并替换所有字符呢? 进行过滤时,没有必要创建一个空字符串。

最重要的是:我真的需要正则表达式吗? (这里没有!)

您在这里实际上不需要正则表达式。 由于您知道分隔符的大小和位置,因此可以像这样简单地检查:

if line[0] != "*": 

这将比正则表达式更快。 它们是非常强大的工具,可以弄清楚难题,但是对于具有固定宽度和位置的定界符,您实际上并不需要它们。 正则表达式比使用此信息的方法要昂贵得多。

你可以做:

print '\n'.join(re.findall(r'^[^*].*$', ''.join(f), re.M))

例:

txt='''\
words
*remove me
words
words
*remove me '''

import StringIO

f=StringIO.StringIO(txt)

import re

print '\n'.join(re.findall(r'^[^*].*$', ''.join(f), re.M))

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM