在Python中搜索、插入和替换文本的前一行
我有一个包含以下信息的文本文件(示例) 等等 我想做的是找到一个组合,例如,text8 text9用text10替换它,并在它旁边创建一个新句子。最终结果如下:在Python中搜索、插入和替换文本的前一行,python,Python,我有一个包含以下信息的文本文件(示例) 等等 我想做的是找到一个组合,例如,text8 text9用text10替换它,并在它旁边创建一个新句子。最终结果如下: a = text1 text2 text3 text4 b = text1 text8 text9 text5 b1 = text1 text10 text5 c = text6 text5 text1 text9 d = text5 text4 text2 text9 import re old = 'text8 text9' n
a = text1 text2 text3 text4
b = text1 text8 text9 text5
b1 = text1 text10 text5
c = text6 text5 text1 text9
d = text5 text4 text2 text9
import re
old = 'text8 text9'
new = 'text10'
text = open('file.txt').read()
new_lines = []
for line in text.split('\n'):
# Replace all matches in one line in one go
new_line = line.replace(old, new)
new_lines.append(line)
# There is a match; increment number
if new_line != line:
# Get number before equals sign
parts = new_line.split(' =', 1)
old_number = re.search(r'\d+', parts[0])
new_number = 1
# If there is a number, increment
if old_number:
old_number = int(old_number.group(0))
new_number = old_number + 1
parts[0] = parts[0].replace(str(old_number), str(new_number))
# If there is no number, concatenate 1
else:
parts[0] += '1'
new_lines.append(parts[0] + ' =' + parts[1])
print '\n'.join(new_lines)
到目前为止,我已经做了类似的事情(我对python是新手):
但是什么也没发生,而且,这句话也可以出现在其他句子中,如:
a = text1 text2 text3 text4
b = text1 text8 text9 text5
b1 = text1 text10 text5
c = text6 text5 text1 text9
d = text5 text4 text8 text9
d1 = text5 text4 text10
我们可以将所有文件行存储在一些列表
内联线中
,然后循环每一行,查找'text8 text9'
,并将其替换为'text10'
,然后将旧行和新行存储在一个新列表大纲中
,以供以后使用
由于问题歧义而产生的假设:我们使用str.replace
的第三个参数仅替换字符串的第一个匹配项
inlines = [line for line in open('in.txt', 'r')]
outlines = []
for line in inlines:
label = line.split(' ')[0]
newline = line.replace('text8 text9', 'text10', 1).replace(label, f'{label}1', 1)
outlines.append(line)
outlines.append(newline)
# To print the lines as well we can add this
print(line)
print(newline)
你需要像这样的东西:
a = text1 text2 text3 text4
b = text1 text8 text9 text5
b1 = text1 text10 text5
c = text6 text5 text1 text9
d = text5 text4 text2 text9
import re
old = 'text8 text9'
new = 'text10'
text = open('file.txt').read()
new_lines = []
for line in text.split('\n'):
# Replace all matches in one line in one go
new_line = line.replace(old, new)
new_lines.append(line)
# There is a match; increment number
if new_line != line:
# Get number before equals sign
parts = new_line.split(' =', 1)
old_number = re.search(r'\d+', parts[0])
new_number = 1
# If there is a number, increment
if old_number:
old_number = int(old_number.group(0))
new_number = old_number + 1
parts[0] = parts[0].replace(str(old_number), str(new_number))
# If there is no number, concatenate 1
else:
parts[0] += '1'
new_lines.append(parts[0] + ' =' + parts[1])
print '\n'.join(new_lines)
但这不会为多个匹配打印多行。给定一个输入:
a=text1 text2text3text4
b=text1 text8 text9 text5
c=text6 text5 text1 text9
d20=文本5文本4文本2文本8文本9
e60=text5 text4 text2 text8 text9 text8 text9
这将生成输出:
a=text1 text2text3text4
b=text1 text8 text9 text5
b1=文本1文本10文本5
c=text6 text5 text1 text9
d20=文本5文本4文本2文本8文本9
d21=文本5文本4文本2文本10
e60=text5 text4 text2 text8 text9 text8 text9
e61=文本5文本4文本2文本10文本10
您可以在此处运行此示例:
如果内存不是问题,则搜索和替换过程相对简单:
search = "text8 text9"
replace = "text10"
with open("file.txt", "r+") as f:
lines = [] # storage list for (modified) lines
for line in f: # read the file line by line
lines.append(line) # add the current line to the lines list
index = line.find(search) # attempt to find the index of the search string
if index != -1: # search string found in the current line
equals_index = line.find("=") # find where the equals sign is
name = line[:equals_index].strip() + "1" # create a new 'sentence' name
# replace the found string with the 'replace' string
value = line[equals_index+1:index] + replace + line[index + len(search):]
lines.append("{} ={}".format(name, value)) # add the new sentence
# let's write down the updates, you can omit the following if you don't want to
# update the file and use the `lines` list for whatever further manipulation
f.seek(0) # rewind back to the beginning of the file
f.writelines(lines) # write down the lines
f.truncate() # truncate the rest in case the new content is smaller than the old
如果内存有问题,不要存储这些行,而是打开另一个文件流到一个临时文件,直接写入它,而不是附加到行
列表中,最后只需用该临时文件覆盖文件.txt
。当然,您根本不需要更改文件,也可以将行存储到另一个文件中
然而,这并不能正确处理多个“句子”的情况,如:
a = text1 text2 text3 text4
b = text1 text8 text9 text5
b = text1 text8 text9 text5
c = text6 text5 text1 text9
a=text1 text2text3text4
b=text1 text8 text9 text5
b=text1 text8 text9 text5
c=text6 text5 text1 text9
或者如果一行中有多个匹配项,即b=text1 text8 text9 text5 text8 text9
。你必须澄清在这种情况下应该发生什么(以及它们是否可能发生)。这还假设“句子”之间没有空行——如果有,请确保在mach上构建新句子时添加额外的行(即行.append(“\n{}={}\n.format(name,value))
)。此外,如果您的文件是Windows“格式”,您可能必须将行结尾调整为\r\n
如果您想让我们解决这些边缘案例,您必须描述它们。您如何确定新“句子”(b1)的数量?简单整数增量?您可以有多个
b
“句子”吗?您需要修正缩进以使程序合法执行。请阅读并遵循帮助文档中的发布指南。最小、完整、可验证的示例适用于此。如果同一行中出现多个“text8 text9”,该怎么办?是否插入b1
、b2
等?或者你只是对第一次发生感兴趣?这会重复每一行,如果有,只更改text8 text9,并且在等号之前不更新标签。当你可以在彼此之间发生时,这不是一个很好的主意。例如,如果我们要搜索“a”并替换为“b”,而该行是“a”,则实际上有三个重叠的引用。您的方法replace(“aa”、“b”)
返回“bb”,而不是“baa”、“aba”和“aab”。这也强调了问题要求是模糊的。@darksky是的,我注意到了这一点,但意识到我们想要输出哪个选项是非常模糊的。@Pedro感谢您的提醒,我错过了这个要求,并填写了修复答案。