假设我有一个如下格式的文本文件:
***a
foo bar
lorem ipsum
dolor
---a
我想打印***a
和---a
之间的行我正试图用这个来完成:
def printlines():
pattern = open('text.txt').read().splitlines()
for line in pattern:
if line == "***a":
pass
while line != "---a":
print line
else:
pass
但它以无限循环打印***a
。我该如何解决这个问题?
使用状态机。这意味着,一旦你看到你的开场白,就设置一个状态,这样你就知道下面的几行现在与你相关。然后继续寻找结束模式来关闭它:
def printlines():
# this is our state
isWithin = False
with open('text.txt') as f:
for line in f:
# Since the line contains the line breaking character,
# we have to remove that first
line = line.rstrip()
# check for the patterns to change the state
if line == "***a":
isWithin = True
elif line == "---a":
isWithin = False
# check whether we’re within our state
elif isWithin:
print line
由于我们只在isWithin
状态下打印一次,所以我们可以很容易地跳过***a
/---a
模式的任何部分。因此,处理以下文件将正确打印出Hello
和World
,而不打印其他内容:
Foo
***a
Hello
---a
Bar
***a
World
---a
Baz
此外,您应该使用with
语句打开文件,并直接迭代文件对象,而不是读取它并调用splitlines()
。这样可以确保文件正确关闭,并且只读取一行又一行,从而提高内存效率。
使用中断并继续:
def printlines():
pattern = open('text.txt').read().splitlines()
for line in pattern:
if line == "***a":
continue
if line == "---a":
break
print line
中断
break语句与C中的语句一样,从最小的封闭中断开for或while循环。
继续
continue语句也是从C中借来的,继续下一个循环的迭代。
如果你有多次出现,你可以在到达起跑线时启动一个内部循环,这相当于你的while试图做的事情:
with open("test.txt") as f:
for line in f:
if line.rstrip() == "***a":
print("")
for line in f:
if line.rstrip() == "---a":
break
print(line.rstrip())
适用于:
***a
foo bar
lorem ipsum
dolor
---a
***a
bar bar
foobar
foob
---a
将输出:
foo bar
lorem ipsum
dolor
bar bar
foobar
foob
如果你想要没有换行符的行,我们可以map
关闭它们,并且仍然逐行迭代:
with open("test.txt") as f:
# itertools.imap python2
f = map(str.rstrip, f)
for line in f:
if line == "***a":
print("")
for line in f:
if line == "---a":
break
print(line)