在 Python 中获取两条相同行之间的文本
Get text between two identical lines in Python
我是 Python 的新手。我经常使用 Perl,听说 Python 通常更擅长解析文本,所以我想试一试,但我想不出最简单的方法(有关信息,我已经在Perl,但它花了我几个,缓慢而丑陋的循环):
我想读取一个大文件并提取以相同模式开头的两行之间的文本块,例如:
!NAME: "N0", DESCR: "Netnt Etrnet"
!NAME: "cp0", DESCR: "Cle R0"
!NAME: "slt R1", DESCR: "RSt"
>>!NAME: "moe R1", DESCR: "ASessor 1,bps"
>>!PID: A9-55
>>!VID: G0984981
>>!SN: SEDGH25443N51E
!NAME: "SDFGSDFG: FGT/0", DESCR: "VFDFGX1"
!NAME: "JQFHF1", DESCR: "VNQDF2"
当然“>>”不是文本文件的一部分,它只是为了显示我要检索的行。
所以回顾一下:我想打印所有块(文件中有更多块),其中块的第一行以“!NAME”开头,并且在下一个“!NAME”之前有其他行.
我不关心连续有两个“!NAME:”的块。
这只是第一步,稍后我将尝试检索此块的值以创建哈希(或字典或任何与 python 中的哈希等效的东西)。但是我已经卡在了第一步所以我寻求帮助哈哈。
谢谢!
with open("in.txt") as f:
prev = ""
for line in f:
if not line.startswith("!NAME:"):
print(prev.rstrip())
print(line.rstrip())
for line in f:
if line.startswith("!NAME:"):
prev = line
break
print(line.rstrip())
prev = line
prev = line
如果要存储每个部分,可以使用字典:
from itertools import count
from collections import defaultdict
cn = count()
sections = defaultdict(str)
with open("log.txt") as f:
prev = ""
for line in f:
if not line.startswith("!NAME:"):
key = next(cn)
sections[key] += prev
sections[key] += line
for line in f:
if line.startswith("!NAME:"):
break
sections[key] += line
prev = line
prev = line
print(d)
defaultdict(<class 'str'>, {0: '!NAME: "moe R1", DESCR: "ASessor 1,bps"\n!PID: A9-55\n!VID: G0984981\n!SN: SEDGH25443N51E\n'})
为确保您只找到前面有 !Name 的部分,请确保前一行以 !Name 开头:
with open("log.txt") as f:
prev = ""
for line in f:
if not line.startswith("!NAME:") and prev.startswith("!NAME:"):
key = next(cn)
sections[key] += prev
sections[key] += line
for line in f:
if line.startswith("!NAME:"):
break
sections[key] += line
prev = line
prev = line
或者,您可以使用 itertools
。
- 忽略文件中的所有内容,直到第一个
!NAME
- 按行是否以
!NAME
开头 分组
- 将其分组,其中第一对是
!NAME
行,第二对是下一个 !NAME
或 EOF 之前的所有内容
- 在输出中包含
!NAME
行的最后一项,其中至少有一行不是 !NAME
代码:
from itertools import groupby, izip_longest, dropwhile
with open('inputfile') as fin:
stripped = (line.strip() for line in fin)
start_at = dropwhile(lambda L: not L.startswith('!NAME'), stripped)
grouped = (list(g) for k, g in groupby(start_at, lambda L: L.startswith('!NAME')))
for name, rest in izip_longest(*iter([grouped] * 2), fillvalue=[]):
if rest:
print name[-1]
print '\n'.join(rest)
给出:
!NAME: "moe R1", DESCR: "ASessor 1,bps"
!PID: A9-55
!VID: G0984981
!SN: SEDGH25443N51E
我是 Python 的新手。我经常使用 Perl,听说 Python 通常更擅长解析文本,所以我想试一试,但我想不出最简单的方法(有关信息,我已经在Perl,但它花了我几个,缓慢而丑陋的循环):
我想读取一个大文件并提取以相同模式开头的两行之间的文本块,例如:
!NAME: "N0", DESCR: "Netnt Etrnet"
!NAME: "cp0", DESCR: "Cle R0"
!NAME: "slt R1", DESCR: "RSt"
>>!NAME: "moe R1", DESCR: "ASessor 1,bps"
>>!PID: A9-55
>>!VID: G0984981
>>!SN: SEDGH25443N51E
!NAME: "SDFGSDFG: FGT/0", DESCR: "VFDFGX1"
!NAME: "JQFHF1", DESCR: "VNQDF2"
当然“>>”不是文本文件的一部分,它只是为了显示我要检索的行。
所以回顾一下:我想打印所有块(文件中有更多块),其中块的第一行以“!NAME”开头,并且在下一个“!NAME”之前有其他行.
我不关心连续有两个“!NAME:”的块。
这只是第一步,稍后我将尝试检索此块的值以创建哈希(或字典或任何与 python 中的哈希等效的东西)。但是我已经卡在了第一步所以我寻求帮助哈哈。
谢谢!
with open("in.txt") as f:
prev = ""
for line in f:
if not line.startswith("!NAME:"):
print(prev.rstrip())
print(line.rstrip())
for line in f:
if line.startswith("!NAME:"):
prev = line
break
print(line.rstrip())
prev = line
prev = line
如果要存储每个部分,可以使用字典:
from itertools import count
from collections import defaultdict
cn = count()
sections = defaultdict(str)
with open("log.txt") as f:
prev = ""
for line in f:
if not line.startswith("!NAME:"):
key = next(cn)
sections[key] += prev
sections[key] += line
for line in f:
if line.startswith("!NAME:"):
break
sections[key] += line
prev = line
prev = line
print(d)
defaultdict(<class 'str'>, {0: '!NAME: "moe R1", DESCR: "ASessor 1,bps"\n!PID: A9-55\n!VID: G0984981\n!SN: SEDGH25443N51E\n'})
为确保您只找到前面有 !Name 的部分,请确保前一行以 !Name 开头:
with open("log.txt") as f:
prev = ""
for line in f:
if not line.startswith("!NAME:") and prev.startswith("!NAME:"):
key = next(cn)
sections[key] += prev
sections[key] += line
for line in f:
if line.startswith("!NAME:"):
break
sections[key] += line
prev = line
prev = line
或者,您可以使用 itertools
。
- 忽略文件中的所有内容,直到第一个
!NAME
- 按行是否以
!NAME
开头 分组
- 将其分组,其中第一对是
!NAME
行,第二对是下一个!NAME
或 EOF 之前的所有内容
- 在输出中包含
!NAME
行的最后一项,其中至少有一行不是!NAME
代码:
from itertools import groupby, izip_longest, dropwhile
with open('inputfile') as fin:
stripped = (line.strip() for line in fin)
start_at = dropwhile(lambda L: not L.startswith('!NAME'), stripped)
grouped = (list(g) for k, g in groupby(start_at, lambda L: L.startswith('!NAME')))
for name, rest in izip_longest(*iter([grouped] * 2), fillvalue=[]):
if rest:
print name[-1]
print '\n'.join(rest)
给出:
!NAME: "moe R1", DESCR: "ASessor 1,bps"
!PID: A9-55
!VID: G0984981
!SN: SEDGH25443N51E