簡體   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