问题描述
在python脚本或IDLE shell中,我们可以使用双引号"
或单引号'
或三个单引号或双引号的组合来打印文本(主要用于文档字符串){{1} }.
我正在处理一些文本并尝试了以下内容:
'''
扫描文本时出现 EOL。
然后我这次尝试使用 5 个引号,即 ''''4''''
,输出为 '''''4'''''
。
最后,我用大量引号尝试了同样的方法:
输入
"''4"
输出
>>> '''''''''''''''''''''''''''''ff'''''''''''''''''''''''''''
我无法理解为什么在给定如此大量的 "''ff"
的情况下 python 会返回这样的输出。
问题:它是如何显示出如此异常的输出,其背后的逻辑是什么?
解决方法
'''''4'''''
被解析为
-
'''
(开放字符串字面量) -
''4
(字符串的内容) -
'''
(关闭字符串文字) -
''
(空字符串文字)
我不会做整个长篇。但是每个 ''''''
都是一个空的三引号字符串文字,所以它们是相同的。
考虑一个简单的 FSM(三种主要状态:在代码中、在字符串中、在文档字符串中)使用输入来处理单引号。当它在代码中并且遇到连续三个引号时,它进入文档字符串状态。它保持在 docstring 状态,直到遇到三个相同类型的引号。当它在代码中并且连续遇到少于三个引号时,它进入字符串状态,并保持该状态直到遇到(未转义的)引号(可能是立即)。
当这个FSM在code状态遇到一长串引号(匹配RE /'{3,}/
)时,进入和退出docstring状态(没有遇到非定界符,所以字符串都是空的) 直到最后几个引号字符,此时它仍处于文档字符串状态(并且任何剩余的引号都在字符串中)或处于代码状态,并且任何剩余的引号都被解释为字符串分隔符。如果它处于字符串或文档字符串状态,遇到一长串引号,它将首先转换到代码状态,然后每三个引号将在代码和文档字符串状态之间转换。末尾的任何剩余引号都按前面所述进行解释。
实际的 FSM 将需要 3 个主要状态以外的其他状态,但它们是一个实现细节,在概念上并不重要。通过复制单引号状态和转换并根据双引号进行适当的修改,FSM 也可以很容易地扩展到处理双引号。
编写 FSM 的正式描述并根据连续引用的计数从初始状态计算最终状态(即编写函数 end_state(initial_state,consecutive_quote_count)
)作为练习。