鱼C论坛

 找回密码
 立即注册
查看: 32|回复: 0

[技术交流] 关于原始字符串、单双三引号、反斜杠的学习思考

[复制链接]
发表于 昨天 17:33 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
本帖最后由 Ganzi 于 2025-11-21 17:33 编辑

出发点是小甲鱼老师在003讲中留的课后作业
“非要在原始字符串的结尾添加反斜杠”一题
将习题和答案简化后如下:
  1. raw = r'C:\P\F\G'
  2. string = r'C:\P\F\G''\\'
复制代码


作为刚开始学习编程和python的新手
以下是我的一些思考和学习
希望可以给同样困惑的同伴一些启发
也欢迎各位大佬多多指教


一开始 我的想法很简单 \\是反斜杠的转义 则有:
  1. string = r'C:\P\F\G'\\
  2. SyntaxError: unexpected character after line continuation character
  3. string = 'C:\P\F\G'\\
  4. SyntaxError: unexpected character after line continuation character
复制代码

无论是否是原始字符串 都报了相同的错误
这是因为\被python识别为续行符了 所以跟在后面的\就成了不应该存在的符号
那么把反斜杠直接写进字符串里呢? 原始字符串里反斜杠不转义 则有:
  1. string = r'C:\P\F\G\'
  2. SyntaxError: unterminated string literal (detected at line 1); perhaps you escaped the end quote?
  3. string = 'C:\P\F\G\'
  4. SyntaxError: unterminated string literal (detected at line 1); perhaps you escaped the end quote?
复制代码

无论是否是原始字符串 都报了相同的错误 它提示我没有结尾的引号
那么把引号补上呢?则有:
  1. string = r'C:\P\F\G\''
  2. string
  3. "C:\\P\\F\\G\\'"
  4. string = 'C:\P\F\G\''
  5. string
  6. "C:\\P\\F\\G'"
复制代码

原始字符串的情况 结尾的\' 是\和'两个字符
普通字符串的情况 结尾的\' 被识别为一个'的转义
那么把\\写进去呢?
  1. string = r'C:\P\F\G\\'
  2. string
  3. 'C:\\P\\F\\G\\\\'
  4. string = 'C:\P\F\G\\'
  5. string
  6. 'C:\\P\\F\\G\\'
复制代码

原始字符串的情况 结尾的\\是\和\两个字符
普通字符串的情况 结尾的\\被识别为一个\的转义
那么如果是按照答案那样呢?是不是原始字符串会对结果有影响吗?
  1. string = r'C:\P\F\G''\\'
  2. string
  3. 'C:\\P\\F\\G\\'
  4. string = 'C:\P\F\G''\\'
  5. string
  6. 'C:\\P\\F\\G\\'
复制代码

答案是一致的 python中支持依次输入字符串 自动拼接为一整个字符串
而原始字符串和普通字符串拼接以后 就变成了一个普通的字符串了
那么如果拼过来的也是原始字符串呢?
  1. string = r'C:\P\F\G'r'\\'
  2. string
  3. 'C:\\P\\F\\G\\\\'
  4. string = 'C:\P\F\G'r'\\'
  5. string
  6. 'C:\\P\\F\\G\\\\'
复制代码

答案也是一致的

普通的字符串前缀r 就变成了原始字符串
原始字符串前加str 就变回了普通字符串

多行输入的常见情况:
        反斜杠 (每行末尾)
        括号 (圆、方、花)
        连续引号(三个连续的单/双引号)
        以冒号结尾的语句 (if、for...)

到目前为止 上述的“escape end quote”还未真正解决(救……)
在搜索学习中 我发现了这样一篇帖子:
“Why can't Python's raw string literals end with a single backslash?”
(没权限发链接 就只发标题了^-^)
归纳一下就是说:
虽然原始字符串总是将\视为没有转义能力的符号
但是它不能以奇数形式存在于字符串的结尾
它会转义掉单引号和双引号 三引号没事
并且这种转义不会被视为字符串的终点

仿照帖子中的案例 我自己也写了几个 加深理解
  1. r'\''\\'
  2. SyntaxError: unexpected character after line continuation character
  3. r'\\''\\'
  4. '\\\\\\'
  5. r'''\''''''
  6. "\\'"
复制代码

第二个 就是原始字符串和普通字符串的简单拼接
第三个 因为\不会转义''' 所以前半部分是\
后半部分的'''直接被识别成了另一个普通字符串 里面只有一个'
拼接成一个\' 转义一下就是\\'

第一个 比较复杂 我以为是原始字符r'\'和普通字符'\\'的拼接
但是实际上不是 而且报错也没有像一开始那样 提示引号不全
而是变成了 换行符后不能存在的符号……?

但是这好奇怪 一样的结构 它为什么觉得没错呢?
和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——————
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-11-22 05:07

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表