python深层知识点--持续更新中

python深层知识点

字符串表示

'''
在表示或敲打字符串时,我们必须认识到一点,即,该字符串的“表示形式”或语法层次是什么?
1 若它是一种原始的,自然的形式,如字符串:"大自然", 代码敲击时,也为"大自然"。
"大自然" 与 r"大自然" 解释上是一样的,这种形式不涉及python语言的转义语法。
用print()作用于此类形式的结果是一样的;用repr()作用于此类形式的结果是一样的。
但print()与repr()作用于相同字符串时,通常结果不一样!
   
2 若涉及转义语法,如: "\""与 r"\"" 在解析后的输出是不一样的。这类字符串含有转义符号\,
print()作用的结果不一样,repr()作用的结果也不一样。
在转义语言的作用下,要用使得print()输出反斜杠,唯一的方法是:print("\\"),
用print(r"\")是会报错的,可能原因是,必须先确保字符串成功闭合在考虑r的作用,
且\后跟引号时,\有转义作用,此时转义的作用先于r的作用,使得字符串闭合失败。
产生EOF报错,即r"\"是一种错误表达!
但,print(r"\\")的结果是\\ ,即可能转义的作用后没报错,r的作用才能够进行。
通常,编程考虑的就是此类字符串。

3 若涉及正则表达式的匹配,
在正则表达式中对于一个反斜杠\,需要使用普通字符串\\\\,
或者是使用原始字符串中的r"\\"来对其进行匹配。
在正则表达式中\是特殊符号,我们为了匹配到该字符串,取消其在正则表达式中的特殊含义,
就使用\\来匹配正则表达式中的\,
同时又为了取消反斜杠在普通字符串之中的特殊含义,
又需要在之前的基础上再针对每一个反斜杠再增加一个反斜杠来取消其特殊含义,即为\\\\。
当我们使用了原始字符串操作符后,就会取消了在普通字符串之中的转义功能,
而只需要匹配正则表达式中的\,即为r"\\"。

注意:要表示反斜杠的字符串唯一的方法是:"\\", 而用r"\"是一种错误表达!
print()作用的结果是给人看的结果,repr()作用的结果是给机器解释的输入。
在正则表达式中\是特殊符号,因此要多一层转义。
'''

========================

# coding=UTF-8
s="物品\t单价\t数量\n包子\t1\t2"
print(s)  # 给人看的结果 
print(repr(s)) # 机器解释的输入

# 运行结果:
# 物品    单价    数量
# 包子    1       2   
# '物品\t单价\t数量\n包子\t1\t2'
r"\""           # 输出:'\\"'   # r表示raw,指原始的字符串,无转义,无解释,之前的样子,
                # 自然的表示形式。其输出是一种转义后的结果。
r"\\\""         # 输出:'\\\\\\"'
repr("\"")      # 输出:'\'"\''
repr('\"')      # 输出:'\'"\''
repr("\\\"")    # 输出:'\'\\\\"\''
repr(r'\"')     # 输出:'\'\\\\"\'' 其与repr('\\"')的结果一样
repr(r"\\\"")   # 输出:'\'\\\\\\\\\\\\"\''
# jupyter notebook 中的输出是一种简化后的结果输出
"sd\\\\\"dg"  # 输出:'sd\\\\"dg' 最后一个反斜杠转义了双引号,结果为一种简化
"sd\\\\\'dg"  # 输出:"sd\\\\'dg" 最后一个反斜杠转义了单引号,结果为一种简化,
              # 其实等价于"sd\\\\'dg"
'sd\\\\\'dg'  # 输出:"sd\\\\'dg" 最后一个反斜杠转义了单引号,结果为一种简化
"sd\\\\'dg"   # 输出:"sd\\\\'dg" ,结果已最简化
r"sd\\\\\"dg" # 输出:'sd\\\\\\\\\\"dg' # 从结果可以发现,r的作用优先于简化!
print("sd\\\\\"dg") # 输出:sd\\"dg
# 分析:简化的作用优先于print(),在print()内"sd\\\\\"dg"先简化为'sd\\\\"dg',
# 再打印输出为sd\\"dg
repr("sd\\\\\"dg") # 输出:'\'sd\\\\\\\\"dg\''
# 分析:简化的作用优先于repr(),在repr()内"sd\\\\\"dg"先简化为'sd\\\\"dg',
# 再输出为'\'sd\\\\\\\\"dg\''
'''
人 → utf-8等字符 → 前后加(单双三)引号 → 原始字符串raw_str → 
① 在print(r_)作用下的结果为自身,
如:print(r"\n\t\v\s\b\f \\\\\"kt\\") 的结果为 \n\t\v\s\b\f \\\\\"kt\\
这种情况的特点是不以连续奇数个反斜杠作为结尾。
② 要让print()的结果是以连续奇数个反斜杠作为结尾,需使用字符串的转义,
如:print("\\\\\\")的结果为\\\
至此,所有字符串得到表示。
所有字符串 → (解释器) →   机器解释的字符串:
repr(r"\n\t\v\s\b\f \\\\\"kt\\") 的结果为:
'\'\\\\n\\\\t\\\\v\\\\s\\\\b\\\\f \\\\\\\\\\\\\\\\\\\\"kt\\\\\\\\\''
若人们看到的字符串是\n\t\v\s\b\f \\\\\"kt\\,则解释器读取的字符串时
\'\\\\n\\\\t\\\\v\\\\s\\\\b\\\\f \\\\\\\\\\\\\\\\\\\\"kt\\\\\\\\\'
即一个反斜杠对应4个反斜杠。

原始表示        转义表示                           正则表示(解析器读取)
\              \\ (r"\"是错的)                  '\\\\'
\\             \\\\ 或 r"\\"                      '\\\\\\\\'
\\\            \\\\\\(r"\\\"是错的)             '\\\\\\\\\\\\'
x\y            x\y(这里的\并无转义的意思)        'x\\\\y'
...
反斜杠在转义表示中,其是否被看作转义是以它和其后的字符组成的字符串是否有特殊意义为依据的,
如有特殊意义则该反斜杠表示转义,若无则表示
repr("x\y\\\\n\ndf\\") 结果为     "'x\\\\y\\\\\\\\n\\ndf\\\\'"
repr("x\\y\\\\n\ndf\\") 结果也为 "'x\\\\y\\\\\\\\n\\ndf\\\\'"
分析:在转义表示下x\y与x\\y,由于\y并无特殊意义故这里的\原始表示为一个\
\\\\n中每两个\实际表示一个\,故在转义表示下的\\\\n原始表示为\\n
\ndf中\n有特殊含义,在转义表示下的\ndf原始表示为:二分之一个\并上ndf
末尾的\\原始表示为一个\
将上面的原始表示结果中的\的数量乘以4得:
x\\\\y
\\\\\\\\n
\\ndf
\\\\
合并结果得:"'x\\\\y\\\\\\\\n\\ndf\\\\'"

对单引号或双引号进行转义的字符串,这种字符串转换为解释器解释的字符串时,
需要考虑解析后的字符串内的使用的是单引号还是双引号,来决定是否转义。
如:
repr("\\\y\n\\\'")  结果为:'"\\\\\\\\y\\n\\\\\'"'
repr("\\\y\n\\\"")  结果为:'\'\\\\\\\\y\\n\\\\"\'' 这里的双引号无需被转义
repr('\\\y\n\\"')   结果为:'\'\\\\\\\\y\\n\\\\"\'' 输入少了一个\,但结果与上面相同


'''

================================

repr("x\y") == repr("x\\y") # 结果为 True
repr("x\\\y") # 结果为 "'x\\\\\\\\y'"
"x\\y" == "x\y"  # 结果为 True 结果为:'x\\y'
'''
三重引号''' '''的作用:保留原样输出,多行注释。注意在''' '''内 \ 仍然有转义的功能,
因为其本质上还是一个字符串的表示。

print() 供解释器读取后的显示结果
在print()的作用下'''sd\\\'dg\\''''''sd\\'dg\\'''的结果都是 sd\'dg\ 
因为字符串中的'是否转义不影响解释器的解释,或可认为结果是一样的。
print('''sd\\\'dg\\''')
print('''sd\\'dg\\''')
print("sd\\\'dg\\")
print('sd\\\'dg\\')
以上4式结果都为:sd\'dg\
字符串在解释器中的逻辑过程:
In → 字符串输入 → 是否有r前缀?(字符串以连续奇数个反斜杠作为结尾?报EOF错误:继续):继续 
→  转义 →  简化 → 函数 →  Out 

repr(s) 
repr() 函数将对象转化为供解释器读取的形式。
在repr()的作用下 '''sd\\'dg\\'''"sd\\'dg\\"的结果都是'"sd\\\\\'dg\\\\"'
但两者print结果为: sd\'dg\
在repr()的作用下 '''sd\'dg\\'''"sd\'dg\\"的结果都是'"sd\'dg\\\\"'
但两者print结果为:sd'dg\
jupyter notebook 中:
Int                          Out
repr('''sd\\'dg\\''')        '"sd\\\\\'dg\\\\"'  注意:这里是一对单引号套一对双引号
repr("sd\\'dg\\")            '"sd\\\\\'dg\\\\"'  注意:这里是一对单引号套一对双引号
repr('''sd\\"dg\\''')        '\'sd\\\\"dg\\\\\'' 注意:这里是一对单引号套一对单引号
repr('sd\\"dg\\')            '\'sd\\\\"dg\\\\\''  注意:这里是一对单引号套一对单引号
repr("sd\\\'dg\\")           '"sd\\\\\'dg\\\\"'  注意:这里是一对单引号套一对双引号

'''

转义 escape

# 转义字符           描述
# \(处于行尾位置)  续行符
# \\                反斜杠
# ’                 单引号
# \"                双引号
# \b                退格
# \n                换行
# \v                纵向制表符
# \t                横向制表符
# \r                回车
# \f                换页


# 当\处于语句的行的最末尾且之后无紧随引号时,表示:续行,
# 将下一行的字符串内容与该行的字符串内容合并解析为一个整体,及解析该行时,\之后的\n失效。
new_os = '''\
huawei\'s HarmonyOS is coming\
''' 
# repr(new_os)结果:'"huawei\'s HarmonyOS is coming"'
# print结果:huawei's HarmonyOS is coming
new_os = '''\
huawei\'s HarmonyOS is coming
'''
# print结果:注意:比上例的结果多了一空行
# huawei's HarmonyOS is coming
# 
new_os = '\
huawei\'s HarmonyOS is coming\
'
# print结果:huawei's HarmonyOS is coming 
new_os = '\
huawei\'s HarmonyOS is coming
'
# print结果:SyntaxError: EOL while scanning string literal 
# 这是因为单引号只能用于非长字符串
new_os = '\
huawei\'s HarmonyOS is coming'
# print结果:huawei's HarmonyOS is coming
new_os = '
huawei\'s HarmonyOS is coming'
# print结果:SyntaxError: EOL while scanning string literal 
# 这是因为单引号只能用于非长字符串
new_os = 'huawei\'s HarmonyOS is coming'
# print结果:huawei's HarmonyOS is coming
new_os = 'huawei\'s HarmonyOS is coming\
'
# print结果:huawei's HarmonyOS is coming
print(new_os)
# \ 用于语句字符串拼接时,既可以在表示的字符串整体内,也可以在字符串部分外:
new_os = 'huawei' \
'HarmonyOS' \
' is coming'

print(new_os)
# 结果:huaweiHarmonyOS is coming

正则str

# \d 匹配一个数字
# \D 匹配一个非数字
# \w 匹配一个字母、数字或下划线_
# \W 匹配任何非单词字符, 等价于“[ ^ A-Za-z0-9_]"
# \s 匹配任何空白字符,包括空格、制表符、换页符等等, 等价于[f\n\r\t\v]
# \S 匹配任何非空白字符
# \n 匹配一个换行符
# \r 匹配一个回车符
# \t 匹配一个制表符
# \A 只匹配字符串开始。
# \b 匹配空字符串,但只在单词开始或结尾的位置。

s_test = '"\\\\yd\"dgha"\\kk\\\\\\' # 其正则str: '"\\\\\\\\yd"dgha"'
re.search('\\', s_test).group(0) 
# error: bad escape (end of pattern) at position 0
# re.search是在原始str上查询还是在更合理的str上查询?都不是而是在正则str中查找!
# 因此,在re的pattern中'\\'是不合法的!
# '\\'并不能匹配到原始str的反斜杠,而必须使用'\\\\'

s_test = '"\\\\yd\"dgha"' # 其正则str: '"\\\\\\\\yd"dgha"'
kw1 ='\\\\'
kw2 = '[^\\\\]{1}"' 
#print(s_test)
re.search(kw1+'.*?'+kw2, s_test).group(0)
# 结果为 '\\\\yd"'
# 注意 所有转义字符串在被函数引用时,都会提前被转化为更合理的转义字符串,
# 这是自动进行的!!!
# 在re的pattern中'"','\"','\\"','\\\"',这四者是相同的!!!都为原始str的"

###
content = '''\\"sd\"dg\n\\n\\\y\\y\y\yy"hd"''' 
# 原始str为:'''\"sd"dg换行\n\\y\y\yy"hd"''' 这里的换行请想象为操作
rex_compile = re.compile('\\\\\\\"sd"dg\n\\\\n\\\\\\\\y\\\\y\\\\y\\\yy')   # 1
#rex_compile = re.compile('\\\\\\\"sd"dg\\n\\\\n\\\\\\\\y\\\\y\\\\y\\\yy')  # 2
#rex_compile = re.compile('\\\\\\\"sd"dg\\\n\\\\n\\\\\\\\y\\\\y\\\\y\\\yy') # 3
rex = rex_compile.search(content)
rex.group()
# 结果:'\\"sd"dg\n\\n\\\\y\\y\\y\\yy'
# 以上1,2,3结果是相同的!

本文逻辑图

import graphviz

text000 = '''
digraph str_graph{
    //rankdir=TB
    //"python 字符串处理逻辑" [shape = "plaintext" fontsize = "13"]
    node [fontname="SimSun"]
    edge [fontname="SimSun"]
    "原始str" [shape = "box"]
    "转义str" [shape = "box"]
    "更合理的转义str(后台自动处理)" [shape = "box"]
    "正则str(解释器读取)" [shape = "box"]
    "更合理的正则str\n(用于re中的pattern)" [shape = "box"]
    
    "原始str" -> "转义str" [fontsize = "10" taillabel = "(尾部不含奇数个反斜杠)加前缀r \n 或 格式转义"]
    "转义str" -> "更合理的转义str(后台自动处理)" 
    [fontsize = "10" minlen = "2" headlabel = "更合理的转义str表示规则:
    ①将转义后无特殊意义的反斜杠数量加倍,如将'反斜杠y'表示为'反斜杠反斜杠y';
    ②将单引号内对双引号转义反斜杠去掉;
    ③将双引号内对单引号转义反斜杠去掉。"]
    "更合理的转义str(后台自动处理)" -> "原始str" [fontsize = "10" 
    label = "print():对特殊意义字符进行特殊处理"]
    "更合理的转义str(后台自动处理)" -> "正则str(解释器读取)" [fontsize = "10" 
    taillabel = "repr():
    ①更合理的转义str内的反斜杠加倍;
    ②前后加上单引号或转义单引号。"]
    
    "正则str(解释器读取)"  -> "更合理的正则str\n(用于re中的pattern)" [fontsize = "10" minlen = "6"
    taillabel = "更合理的正则str表示规则:
    ①连续4个反斜杠,则保留;匹配的是原始str的一个反斜杠;
    ②连续3个反斜杠:
    (1)反斜杠与第4个字符可组成特殊意义,则这3个反斜杠可简写为1个,
    如:'反斜杠反斜杠反斜杠n'简写为'反斜杠n',匹配的是原始str的'换行';
    特别地,若第4个字符为引号,只要不违反单双引号交替使用的规则,甚至可以去掉3个反斜杠;
    (2)反斜杠与第4个字符不可组成特殊意义,则不可简写,
    如:'反斜杠反斜杠反斜杠y',匹配的是原始str的'反斜杠y';
    ③连续2个反斜杠:
    (1)反斜杠与第3个字符可组成特殊意义,则这2个反斜杠可简写为1个,
    如:'反斜杠反斜杠n'简写为'反斜杠n',匹配的是原始str的'换行';
    特别地,若第3个字符为引号,只要不违反单双引号交替使用的规则,甚至可以去掉2个反斜杠;
    (2)反斜杠与第3个字符不可组成特殊意义,则将报错,如:'反斜杠反斜杠y'是非法表达;
    ④连续1个反斜杠:
    (1)反斜杠与第2个字符可组成特殊意义,则保留,如:'反斜杠n'匹配的是原始str的'换行';
    特别地,若第2个字符为引号,只要不违反单双引号交替使用的规则,甚至可以去掉该反斜杠;
    (2)反斜杠与第2个字符不可组成特殊意义,则将报错,如:'反斜杠y'是非法表达。"]
    }
'''

dot = graphviz.Source(text000)
path_temp = "str_graph.png"
dot.view(filename=path_temp, directory="")
dot

在这里插入图片描述

参考

https://www.runoob.com/python/python-func-repr.html
https://blog.csdn.net/weixin_35385983/article/details/99757217

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值