我正在尝试读取制表符分隔文件并收集除控制字符之外的所有字符。如果击中控制字符,则应忽略该行的其余部分。
我使用for..else
loop:
import curses.ascii
input_file = ...
chars = set()
with open(input_file) as file:
for line in file.readlines():
source, target = line.split("\t")
for c in source.strip() + target.strip():
if curses.ascii.iscntrl(c):
print("Control char hit.")
break
chars.add(c)
else:
print("Line contains control character:\n" + line)
continue
print("Line contains no control character:\n" + line.strip())
我希望这可以检查每个角色是否为控制角色,如果它击中一个(break
被触发),跳到下一行,从而触发else
/ { {1}}陈述。
相反,即使continue
子句中的continue
语句从未到达某一行,也会始终触发break
。因此,也永远不会达到最终的if
语句。
我做错了什么?
答案 0 :(得分:1)
如果else
循环从未中断,for
循环的for
块仅执行 。如果行中没有控制字符,您只会在continue
块中看到else
语句。来自for
statement documentation:
当项目耗尽时(当序列为空或迭代器引发
StopIteration
异常时),将执行else
子句中的套件(如果存在),并执行循环终止。在第一个套件中执行的
break
语句终止循环而不执行else
子句的套件。
检查一行中是否有控制字符的更好的测试是any()
function使用generator expression:
if any(curses.ascii.iscntrl(c) for c in source.strip() + target.strip()):
print("Line contains control character:\n" + line)
continue
或者你可以使用正则表达式;这样做会更快,因为在C代码中完成循环文本而不必在新的str
对象中打包每个单独的字符:
import re
control_char = re.compile(r'[\x00-\x31]')
if control_char.search(source.strip() + target.strip()):
print("Line contains control character:\n" + line)
continue