我建议您在看到
#
字符时不要忽略整行。只是忽略其余部分。这可以通过名为
partition
的字符串方法轻松完成:
with open("filename") as f:
for line in f:
line = line.partition('#')[0]
line = line.rstrip()
# ... do something with line ...
partition
返回一个元组: 分节线, 该分节线之前的所有内容以及该分节线之后的所有内容。因此, 在使用
[0]
进行索引时, 我们仅将零件放置在剖面线之前。
编辑: 如果您使用的Python版本没有
partition()
, 则可以使用以下代码:
with open("filename") as f:
for line in f:
line = line.split('#', 1)[0]
line = line.rstrip()
# ... do something with line ...
这将使用#字符分割字符串, 然后在分割之前保存所有内容。
1
自变量除以1后,
.split()
方法的执行将停止; 由于我们仅获得第0个子字符串(通过使用
[0]
进行索引), 因此即使您不使用
1
参数Response, 也会得到相同的结果, 但可能会更快。(由于@gnr的注释, 从我的源代码简化而来。我的源代码很乱, 没有充分的理由; 谢谢@gnr。)
您也可以只编写自己的
partition()
版本。这是一个名为
part()
的名称:
def part(s, s_part):
i0 = s.find(s_part)
i1 = i0 + len(s_part)
return (s[:i0], s[i0:i1], s[i1:])
@dalle指出#可以出现在一行上。正确设置它并不容易, 因此我只是忽略了它, 但是我应该说些什么。
如果您的输入文件具有足够简单的规则来使用带引号的字符串, 则并不困难。如果您接受任何有效的Python引号引起来的字符串, 将很困难, 因为存在单行, 双行, 多行反斜杠引号, 行尾转义字符串, 三引号(使用单引号或双引号), 甚至是原来的弦! 正确处理所有这些问题的唯一可能方法是使用复杂的状态机。
但是, 如果我们将自己限于简单的带引号的字符串, 则可以使用简单的状态机来处理它。我们甚至可以在字符串中使用反斜杠双引号。
c_backslash = '\\'
c_dquote = '"'
c_comment = '#'
def chop_comment(line):
# a little state machine with two state varaibles:
in_quote = False # whether we are in a quoted string right now
backslash_escape = False # true if we just saw a backslash
for i, ch in enumerate(line):
if not in_quote and ch == c_comment:
# not in a quote, saw a '#', it's a comment. Chop it and return!
return line[:i]
elif backslash_escape:
# we must have just seen a backslash; reset that flag and continue
backslash_escape = False
elif in_quote and ch == c_backslash:
# we are in a quote and we see a backslash; escape next char
backslash_escape = True
elif ch == c_dquote:
in_quote = not in_quote
return line
我真的不想参与新手问题的复杂性, 但是这个状态机非常简单, 我希望它会很有趣。