在Python中的文本文件中逐个查找行尾
Posted
技术标签:
【中文标题】在Python中的文本文件中逐个查找行尾【英文标题】:find end of line after another in text file in Python 【发布时间】:2021-02-13 18:42:54 【问题描述】:问题
大家好,
在文本文件中我需要用另一个替换未知字符串,
首先要找到它,我需要找到它之前的行'name Blur2' 因为'xpos'有很多行开头:
name Blur2
xpos 12279 # 12279 is the end of line to find and put in a variable
获取未知字符串的代码:
#string to find:
keyString = ' name Blur2'
f2 = open("output_file.txt", 'w+')
with open("input_file.txt", 'r+') as f1:
lines = f1.readlines()
for i in range(0, len(lines)):
line = lines[i]
if keyString in line:
nextLine = lines[i + 1]
print ' nextLine: ',nextLine #result: nextLine: xpos 12279
number = nextLine.rsplit(' xpos ', 1)[1]
print ' number: ',number #result: number: 12279
#convert string to float:
newString = '0\n'.format(int(number)+ 10)
print ' newString: ',newString #result: newString: 12289
f2.write("".join([nextLine.replace(number, str(newString))])) #this line isn't working
f1.close()
f2.close()
所以,我完全改变了方法,但最后一行:f2.write... 没有按预期工作,有人知道为什么吗?
再次感谢您的帮助:)
【问题讨论】:
最后 5 个字符line[-5:]
处理所有行,不包含搜索字符串Blur2
时复制,如果包含Blur2
设置布尔值,如果布尔值设置在下一行,则替换并重置布尔值。也使用上下文管理器:with open("last_file.txt", 'r+') as f1:
谢谢,方法:line[-5:]is 与我的代码完美配合:f2.write("".join([i.replace(i[-10:], newPad) if keyString in i else i for i in f1.readlines()]))
对于替换,不幸的是我需要在替换之前记录它,我不知道如何,我正在尝试通过拆分来获取它...
不要以大写开头的变量,在 Python 约定中是类名
【参考方案1】:
regex 似乎会有所帮助,https://regex101.com/。
正则表达式使用定义模式的语言搜索字符串。我列出了学习模式本身最重要的那些,但它有时比 python 的原生字符串操作更好。
您首先描述您将使用的模式,然后实际编译该模式。对于字符串检查,我使用 r'' 将其定义为原始字符串。这意味着我不必在字符串中转义 \ (例如:打印 \ 将是 print('\') 而不是 print(r'')。
这个正则表达式有几个部分。
\s 表示空格(空格等字符,' ')
\n 或 \r 表示换行符和回车符,[^] 定义不查找的字符(因此 [^\n\r] 搜索不包含换行符或回车符的任何字符),* 表示可以有 0 个或更多的字符表示。正则表达式字符串中的 $ 说明了行尾之前的所有内容。
因此该模式会专门搜索“name Blur2”,然后使用任意数量的空格和换行符。括号允许这是第 1 组(稍后解释)。第二部分 '([^\n\r]*$)' 捕获直到该行末尾为止不是换行符或回车符的任意数量的字符。
括号占组,所以'(name blue\n)'是第1组,你要替换的行'([^\n\r]*$)'是第2组。checkre.sub应该替换第 1 组的全文 和新字符串,所以它用第一行替换第一行,用你的新字符串替换第二行
import re
check = r'(name Blur2\s*\n)([^\n\r]*$)'
checkre = re.compile(check, re.MULTILINE)
checkre.sub(\g<1>+newstring, file)
您需要设置 re.MULTILINE 因为您要检查多行,如果 '\n' 不匹配,您可以使用 [\n\r\z] 获取行的任一端之一,回车,或字符串的绝对结尾。
rioV8 的注释有效,但您也可以使用 '.5$',它占行尾前的任意 5 个字符。这可能会有所帮助
应该可以得到旧字符串
oldstring = checkre.search(filestring).group(1)
我还没玩过span,但是
stringmatch = checkre.search(filestring)
oldstring = stringmatch.group(2)
newfilestring = filestring[0:stringmatch.span[0]] + stringmatch.group(1) + newstring + filestring[stringmatch.span[1]]:]
应该非常接近您要查找的内容,尽管接头可能不完全正确。
【讨论】:
非常感谢,但我不明白什么时候记录字符串:12279?我需要记录它,因为稍后我会在数学公式中使用它并写在另一行... 我已经离开了编辑我的问题,我认为我并没有很明确,可能我需要在名称 Blur2 之后拆分 'xpos' 以获得数字吗? 我可能会尝试编辑这个最终回答这个问题。正则表达式绝对能找到你需要的东西,它也可以替代它。第二组将返回字符串(我认为是'oldstring=checkre.search(file).group(2)'),但是在不再次搜索的情况下替换文件中的字符串将需要一些编辑/研究。我不知道目前的比较速度是多少,但它不会是最佳的。 是的,这个方法我确实不是很懂,有时间再编辑,我会很高兴的,还是谢谢你的回答! 我对此进行了一些编辑,但我可能会在本周晚些时候尝试不同的答案。您现在拥有的内容相当接近(不使用正则表达式),但我看不到您在哪里编写不需要替换为新文件的行。我会在本周晚些时候尝试花一些时间来玩弄它。【参考方案2】:最初的程序非常接近。我对其进行了一些编辑以调整一些错误的地方。
您最初并没有编写需要替换的行,我不确定您为什么需要加入内容。直接替换数字似乎有效。 Python 不允许在 for 循环中对 i 进行更改,您需要跳过一行,以免将其写入文件,因此我将其更改为 while 循环。无论如何问你有任何问题,但下面的代码似乎工作。
#string to find:
keyString = ' name Blur2'
f2 = open("output_file.txt", 'w+')
with open("test.txt", 'r+') as f1:
lines = f1.readlines()
i=0
while i <len(lines):
line = lines[i]
if keyString in line:
f2.write(line)
nextLine = lines[i + 1]
#end of necessary 'i' calls, increment i to avoid reprinting writing the replaced line string
i+=1
print (' nextLine: ',nextLine )#result: nextLine: xpos 12279
number = nextLine.rsplit(' xpos ', 1)[1]
#as was said in a comment, this coula also be number = nextLine[-5:]
print (' number: ',number )#result: number: 12279
#convert string to float:
newString = '0\n'.format(int(number)+ 10)
print (' newString: ',newString) #result: newString: 12289
f2.write(nextLine.replace(number, str(newString))) #this line isn't working
else:
f2.write(line)
i+=1
f1.close()
f2.close()
【讨论】:
以上是关于在Python中的文本文件中逐个查找行尾的主要内容,如果未能解决你的问题,请参考以下文章