[英]How to extract text part from file using Python & Regular Expressions
[英]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.