我有一些文本文件,我想删除所有以星号(“*”)开头的行。
制作示例:
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
这会产生['','''','','' ,'',' ','',' ','&# 39;,' *',''],这不是goo。
我是一个蟒蛇新手,但我渴望学习。我最终会把它捆绑成一个函数(现在我只想在ipython笔记本中找到它)。
感谢您的帮助!
答案 0 :(得分:1)
你不想要使用[^...]
否定字符类;您现在正在匹配所有字符,但*
或.
字符除外。
*
是一个元字符,您希望将其转义为\*
。 .
'匹配任何字符'语法都需要乘数才能匹配多个字符。不要在这里使用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']
答案 1 :(得分:1)
您的正则表达式似乎不正确:
[^*.]
表示匹配任何非^
,*
或.
的字符。在括号表达式中,第一个^
之后的所有内容都被视为文字字符。这意味着在表达式中.
匹配。字符,而不是通配符。
这就是为"*"
开头*
行的原因,你要替换除*
之外的所有字符!您还可以在原始字符串中保留任何.
。由于其他行不包含*
和.
,因此所有字符都将被替换。
如果您想匹配以*
开头的行:
^\*.*
可能更容易的是这样的事情:
pat = re.compile("^[^*]")
for line in contents:
if re.search(pat, line):
new_contents.append(line)
此代码只保留不以*
开头的任何行。
在模式^[^*]
中,第一个^
匹配字符串的开头。表达式[^*]
匹配除*
之外的任何字符。因此,此模式一起匹配不是*
的字符串的任何起始字符。
使用正则表达式时,真正考虑这是一个很好的技巧。您是否只需要断言字符串,是否需要更改或删除字符串中的字符,是否需要匹配子字符串?
就python而言,你需要考虑每个函数给你的内容以及你需要做些什么。有时候,就像在我的例子中,你只需要知道找到了一个匹配。有时您可能需要对匹配做一些事情。
有时re.sub
不是最快或最好的方法。当你可以完全跳过这一行时,为什么还要费心去掉每一行并替换所有的字符呢?在过滤时,制作一个空字符串是没有意义的。
最重要的是:我真的需要正则表达式吗? (在这里你没有!)
这里你真的不需要正则表达式。由于您知道分隔符的大小和位置,因此可以像这样检查:
if line[0] != "*":
这比正则表达式更快。它们是非常强大的工具,可以很好地解决问题,但对于具有固定宽度和位置的分隔符,您并不真正需要它们。正则表达式比使用此信息的方法昂贵得多。
答案 2 :(得分: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))