关于原始字符串、单双三引号、反斜杠的学习思考
本帖最后由 Ganzi 于 2025-11-21 17:33 编辑出发点是小甲鱼老师在003讲中留的课后作业
“非要在原始字符串的结尾添加反斜杠”一题
将习题和答案简化后如下:
raw = r'C:\P\F\G'
string = r'C:\P\F\G''\\'
作为刚开始学习编程和python的新手
以下是我的一些思考和学习
希望可以给同样困惑的同伴一些启发
也欢迎各位大佬多多指教{:7_130:}
一开始 我的想法很简单 \\是反斜杠的转义 则有:
string = r'C:\P\F\G'\\
SyntaxError: unexpected character after line continuation character
string = 'C:\P\F\G'\\
SyntaxError: unexpected character after line continuation character
无论是否是原始字符串 都报了相同的错误
这是因为\被python识别为续行符了 所以跟在后面的\就成了不应该存在的符号
那么把反斜杠直接写进字符串里呢? 原始字符串里反斜杠不转义 则有:
string = r'C:\P\F\G\'
SyntaxError: unterminated string literal (detected at line 1); perhaps you escaped the end quote?
string = 'C:\P\F\G\'
SyntaxError: unterminated string literal (detected at line 1); perhaps you escaped the end quote?
无论是否是原始字符串 都报了相同的错误 它提示我没有结尾的引号
那么把引号补上呢?则有:
string = r'C:\P\F\G\''
string
"C:\\P\\F\\G\\'"
string = 'C:\P\F\G\''
string
"C:\\P\\F\\G'"
原始字符串的情况 结尾的\' 是\和'两个字符
普通字符串的情况 结尾的\' 被识别为一个'的转义
那么把\\写进去呢?
string = r'C:\P\F\G\\'
string
'C:\\P\\F\\G\\\\'
string = 'C:\P\F\G\\'
string
'C:\\P\\F\\G\\'
原始字符串的情况 结尾的\\是\和\两个字符
普通字符串的情况 结尾的\\被识别为一个\的转义
那么如果是按照答案那样呢?是不是原始字符串会对结果有影响吗?
string = r'C:\P\F\G''\\'
string
'C:\\P\\F\\G\\'
string = 'C:\P\F\G''\\'
string
'C:\\P\\F\\G\\'
答案是一致的 python中支持依次输入字符串 自动拼接为一整个字符串
而原始字符串和普通字符串拼接以后 就变成了一个普通的字符串了
那么如果拼过来的也是原始字符串呢?
string = r'C:\P\F\G'r'\\'
string
'C:\\P\\F\\G\\\\'
string = 'C:\P\F\G'r'\\'
string
'C:\\P\\F\\G\\\\'
答案也是一致的
普通的字符串前缀r 就变成了原始字符串
原始字符串前加str 就变回了普通字符串
多行输入的常见情况:
反斜杠 (每行末尾)
括号 (圆、方、花)
连续引号(三个连续的单/双引号)
以冒号结尾的语句 (if、for...)
到目前为止 上述的“escape end quote”还未真正解决(救……)
在搜索学习中 我发现了这样一篇帖子:
“Why can't Python's raw string literals end with a single backslash?”
(没权限发链接 就只发标题了^-^)
归纳一下就是说:
虽然原始字符串总是将\视为没有转义能力的符号
但是它不能以奇数形式存在于字符串的结尾
它会转义掉单引号和双引号 三引号没事
并且这种转义不会被视为字符串的终点
仿照帖子中的案例 我自己也写了几个 加深理解
r'\''\\'
SyntaxError: unexpected character after line continuation character
r'\\''\\'
'\\\\\\'
r'''\''''''
"\\'"
第二个 就是原始字符串和普通字符串的简单拼接
第三个 因为\不会转义''' 所以前半部分是\
后半部分的'''直接被识别成了另一个普通字符串 里面只有一个'
拼接成一个\' 转义一下就是\\'
第一个 比较复杂 我以为是原始字符r'\'和普通字符'\\'的拼接
但是实际上不是 而且报错也没有像一开始那样 提示引号不全
而是变成了 换行符后不能存在的符号……?
但是这好奇怪 一样的结构 它为什么觉得没错呢?{:7_122:}
和deepseek逐一分析后 我才隐约体会到了 所谓的“编译”是什么意思
编译器它不是像人一样 提前“看”到了有两个字符串 需要它去拼接
而是它一个个字符读过去 最后的结果 恰好呈现出了这种宏观的结果现象
r'\''\\'
r 原始字符串——' 字符串开始了——\ 一个用户内容——' 遇到单引号 能否结束字符串?
——向前查看 奇数个\ 这个引号被转义了 继续编译——' 向前查看 这个引号正常 字符串至此结束
——\ 续行——\ 不应该在换行续接符号后面存在的奇怪符号——报错 SyntaxError “unexpected character”
string = r'C:\P\F\G\'
string 一个变量——= 赋值——r 原始字符串——' 字符串开始了——C:\P\F\G 一些无人在意的用户内容——' 遇到单引号 能否结束字符串?
——向前查看 奇数个\ 这个引号被转义了 继续编译——没有了 报错 SyntaxError“escape the end quote”
至此 所有疑问都有了答案
综上所述 梳理一下:
字符串开始后 编译遇到单、双引号 向前查看
——偶数个\(含0个)——不转义 字符串到此结束 继续编译后续代码
——奇数个\——转义掉这个引号(无论是原始还是普通字符串)认为字符串未结束并继续编译后续代码
——————THE END——————
页:
[1]