在Python中替换文件中的特定字符串

时间:2019-03-02 17:18:45

标签: python file replace io

首先,因为我之前曾被一次电源出差的人烧死,所以这个问题不适合家庭作业。

无论如何,我有一个类似于以下内容的文本文件:

####
# File section 1
####

1.0   abc   Description1
6.5   def   Description2
1.0 2.0 3.0   ghi   Description3
11    jkl   Description

####
# File section 2
####

1.0   abc   Description1
12.5   def   Description2
1.0 2.0 3.0   ghi   Description3
11    jkl   Description

#### End file

我想在两行中替换字符串“ 1.0”:

1.0   abc   Description1

但是,请不要在行中使用“ 1.0”字符串:

1.0 2.0 3.0   ghi   Description3

我正在使用的当前代码是:

with open('sample_file.txt','r') as file:
    filedata = file.read()
    filedata = filedata.replace('1.0','2.0')
with open('sample_file.txt','w') as file:
    file.write(filedata)

但是结果是所有出现的“ 1.0”都被替换了。然后,我必须回到文件中,并更正错误。我想得到的结果文件是:

####
# File section 1
####

2.0   abc   Description1
6.5   def   Description2
1.0 2.0 3.0   ghi   Description3
11    jkl   Description

####
# File section 2
####

2.0   abc   Description1
12.5   def   Description2
1.0 2.0 3.0   ghi   Description3
11    jkl   Description

#### End file

我该怎么办?我找不到解决此类问题的示例解决方案。谢谢大家的帮助。

编辑:我的错误不明确,但我要替换的字符串并不总是“ 1.0”,也不总是3个字符长。例如,它可以是“ -12.3”。我想使代码尽可能通用。

我还尝试使用rsplit将空格作为定界符来隔离第一个字符串,但这似乎不适用于文件写入。

======================

EDIT2:我发现了一种方法,尽管这似乎是一种绕行方法:

with open('sample_file.txt','r') as file:
    filedata = file.readlines()
        for line in filedata:
            if 'abc' in line:
                oriline = line
                newline = line.replace(str(spk),str(newspk))
with open('sample_file.txt','r') as file:
    filedata = file.read()
    filedata = filedata.replace(str(oriline),str(newline))
with open('sample_file.txt','w') as file:
    file.write(filedata)

基本上,它将打开文件,逐行读取包含我想要的特定字符串的整行,然后将其存储到内存中。然后再次打开文件,阅读所有内容,然后替换整个字符串。然后打开文件,然后写入文件。

它可以满足我的要求,但是有没有一种方法可以简化代码?

2 个答案:

答案 0 :(得分:1)

只需使用

with open('sample_file.txt','r') as file:
    filedata = file.read()
    filedata = filedata.replace('1.0   abc','2.0   abc')
with open('sample_file.txt','w') as file:
    file.write(filedata)

代替上面的快捷方式,您可以通过首先定义一个空列表来尝试更一般的情况:

li = []

,然后使用下面的代码(考虑到字符串abc在上述情况下是固定的):

with open('sample_file.txt','r') as file:
for line in file:
        i = line.find('abc',1)
        if i >= 0:
              lineval = line.replace('1.0','2.0')
              li.append(lineval)
        else:
              lineval = line
              li.append(lineval)
j = 0                 
with open('sample_file.txt','w') as file:
    while j < len(li):
        file.write(li[j])           
        j += 1

答案 1 :(得分:0)

正如我在评论中提到的,您可以使用as it should be来匹配您要寻找的模式。您可以在模式中指定 groups (使用( ... )(?P< name ... {{1} })识别模式的各个部分,并专门替换或重复使用这些部分。

类似的事情应该起作用:

)

不使用正则表达式的另一种方法(未经测试):

import re

pattern = (r'^' # The beginning of a line.
           # Match something that looks like a number:
           r'-?'        # 1. Optional: a negative sign.
           r'\d+'       # 2. One or more digits.
           r'([.]\d+)?' # 3. Optional: a decimal point followed by one
                        #    or more digits.
           # The rest of the line:
           r'(?P<rest>'
             r'\s+' # 1. One or more spaces.
             r'abc' # 2. "abc"
             r'\s+' # 3. One or more spaces.
             r'.*'  # 4. Everything remaining.
           r')' 
           r'$') # The end of a line.

# Replace the above pattern with "2.0" followed by whatever we identified
# as "the rest of the line".
replacement = '2.0\g<rest>'

with open('sample_file.txt','r') as file:
    filedata = file.read()

    # re.MULTILINE is needed to treat lines separately.
    filedata = re.sub(pattern, replacement, filedata, flags=re.MULTILINE)
with open('sample_file.txt','w') as file:
    file.write(filedata)

请注意,这与正则表达式(RE)方法并不完全相同(值得注意的区别是它将接受任何浮点数作为第一个标记(例如with open('sample_file.txt','r') as file: lines = file.readlines() with open('sample_file.txt','w') as file: for line in lines: tokens = line.split(maxsplit=2) try: if float(tokens[0]) and tokens[1] == 'abc': tokens[0] = '2.0' except (IndexError, ValueError): pass else: line = ' '.join(tokens) file.write(line) ),并且它将不会可以在执行替换操作后保留空间),但是如果您不熟悉RE,可能会更容易理解。