python3.4如何删除模式字符串匹配后的一段文本

时间:2015-05-04 14:49:57

标签: python regex string

我有一个文件,我需要在字符串模式匹配后删除一段文字。

文件中的文字:

ContentControl

如何搜索domain2,然后删除该行以及下面的7行? 会有很多域名。

4 个答案:

答案 0 :(得分:2)

您可以写NamedTemporaryFile,每次"domain2.com"itertool.islice一致时跳过7行,使用shutil.move替换最后的原始文件:

from tempfile import NamedTemporaryFile
from itertools import islice
from shutil import move

with open("test.txt") as f, NamedTemporaryFile("w",dir=".", delete=False) as temp:   
    for line in f:
        if '"domain2.com"' in line:
            list(islice(f, 7))   
        else:
            temp.write(line)

move(temp.name,"test.txt")

输出:

 zone "domain1.com" {
    type slave;
    masters {10.10.10.1;};
    allow-notify{10.10.10.1;};
    allow-transfer {trusted;};
    key-directory "/usr/local/etc/namedb/";
    file "/usr/local/etc/namedb/domain1.com.external.signed";
};

delete=False表示文件不会被删除,如果进程中断,则不会将任何内容写入原文,最后我们使用move(temp.name,"test.txt")覆盖原文。

答案 1 :(得分:0)

如果您知道它总是7行,则以下正则表达式选择它们:

[^\n]*domain2([^\n]*\n){7}

我不知道如何在python中这样做,但我认为如果你知道python会很容易理解。

答案 2 :(得分:0)

import re
p = re.compile(ur'zone.*?\bdomain2\b.*?{[\s\S]*?\n};')
test_str = u"zone \"domain1.com\" {\n type slave;\n masters {10.10.10.1;};\n allow-notify{10.10.10.1;};\n allow-transfer {trusted;};\n key-directory \"/usr/local/etc/namedb/\";\n file \"/usr/local/etc/namedb/domain1.com.external.signed\";\n};\nzone \"domain2.com\" {\n type slave;\n masters {10.10.10.1;};\n allow-notify{10.10.10.1;};\n allow-transfer {trusted;};\n key-directory \"/usr/local/etc/namedb/\";\n file \"/usr/local/etc/namedb/domain2.com.external.signed\";\n};"
subst = u""

result = re.sub(p, subst, test_str)

答案 3 :(得分:0)

如果要在较大的文件上使用正则表达式,请使用mmap

import mmap
import re
from tempfile import NamedTemporaryFile

with open(ur_fn, 'r+') as tgt, NamedTemporaryFile(dir='/tmp', delete=False) as out:
    mm=mmap.mmap(tgt.fileno(), 0)
    fn=out.name
    pat=re.compile(r'^(\s*zone "domain.*?)(?=^\s*zone|\Z)', flags=re.S | re.M)
    for i, block, span in ((n, m.group(1), m.span()) for n,m in enumerate(pat.finditer(mm))):
        if "domain2.com" in block:
            continue
        else:
            out.write(block)

with open(fn) as inf:
    print(inf.read())   # replace this with copying the file onto orig, etc    

然后将临时文件复制到原始文件中。

如果您的文件在目标之后具有7行的绝对模式 - Padraic Cunningham的solution更好。如果你有可变行块或用正则表达式更好地描述的东西,这种方法很方便。

对于您正在处理的内容,请尝试:

import mmap
import re
from tempfile import NamedTemporaryFile

name="new_domain2.com"

template='''\
zone "%s" {
   type slave;
   masters {108.61.190.64;};
   allow-notify{108.61.190.64;};
   allow-transfer {trusted;};
   key-directory "/usr/local/etc/namedb/";
   file "/usr/local/etc/namedb/nyctelecomm.com.external.signed";
};
'''

with open('/tmp/dms.txt', 'r+') as tgt, NamedTemporaryFile(dir='/tmp', delete=False) as out:
    mm=mmap.mmap(tgt.fileno(), 0)
    fn=out.name
    pat=re.compile(r'^(\s*zone "domain.*?)(?=^\s*zone|\Z)', flags=re.S | re.M)
    for i, block, span in ((n, m.group(1), m.span()) for n,m in enumerate(pat.finditer(mm))):
        if re.match(r'zone "domain2\.com', block):
            out.write(template % name)
        else:
            out.write(block)