[英]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.