这次写这篇博客是一个容易把自己绕糊涂的问题
就是转义问题啦(开练开练)
转义字符和原生字符串:
首先讲一下一些基础的概念
转义字符和原生字符串的区别
‘\n’代表换行,是一个转义字符
r'\n' 代表的是字符串“\n”,并没有换行的意思,就单单是一个字符串,这个就是原生字符串
通俗来讲就是,原生字符串就是你一眼看到的是字符串是什么就是什么,而转义字符就是需要通过转义才能表达出来(是通过\来进行转义的)
先来给个例子:
>>> text1 = '\nB\nb\nB'
>>> text2 = r'\nB\nb\nB' 通过添加r来代表这个是原生字符串
>>> text3 = '\\nB\\nb\\nB' 同过添加\来转义\,让\变成普通字符串(哎呀呀,有点晕)
>>> print(text1) 其实,\\就是代表字符串\,因为\是具有转义的意思,
前面的一个\,把后面的\转义成一个字符串 \
B
b
B
>>> print(text2)
\nB\nb\nB
>>> print(text3)
\nB\nb\nB
###这里的text2和text3是相同的道理
Python中的转义字符表(这里你就能搞清楚什么东西是带有特殊意义的)
通俗来说就是在Python中反斜杠加上某种东西可以产生不一样的效果
转义字符
|
描述
|
\(在行尾时)
|
续行符
|
\\
|
反斜杠符号
|
\’
|
单引号
|
\”
|
双引号
|
\a
|
响铃
|
\b
|
退格(Backspace)
|
\e
|
转义
|
\000
|
空
|
\n
|
换行
|
\v
|
纵向制表符
|
\t
|
横向制表符
|
\r
|
回车
|
\f
|
换页
|
\oyy
|
八进制数yy代表的字符,例如:\o12代表换行
|
\xyy
|
十进制数yy代表的字符,例如:\x0a代表换行
|
\other
|
其它的字符以普通格式输出
|
把话题拉回到正则表达式中
首先说一下的是,在python中反斜杠(\)有转义的意思,那么反斜杠(\)在正则表达式(re)中也是具有转义的意思
所以在正则表达式中转义需要通过两个步骤:
1.在python中先转义(可以通过加r来代表原生字符
或
加多一个反斜杠来转义)
2.在正则表达式中转义
那么我们先看一下在正则表达式中有哪些特殊的符号呢
模式
|
描述
|
^
|
匹配字符串的开头
|
$
|
匹配字符串的末尾。
|
.
|
匹配任意字符,除了
换行符
,当re.DOTALL标记被指定时,则可以匹配包括换行符的任意字符。
|
[...]
|
用来表示一组字符,单独列出:[amk] 匹配 'a','m'或'k'
|
[^...]
|
不在[]中的字符:[^abc] 匹配除了a,b,c之外的字符。
|
re*
|
匹配0个或多个的表达式。
|
re+
|
匹配1个或多个的表达式。
|
re?
|
匹配0个或1个由前面的正则表达式定义的片段,非贪婪方式
|
re{ n}
|
匹配n个前面表达式。例如,"o{2}"不能匹配"Bob"中的"o",但是能匹配"food"中的两个o。
|
re{ n,}
|
精确匹配n个前面表达式。例如,"o{2,}"不能匹配"Bob"中的"o",但能匹配"foooood"中的所有o。"o{1,}"等价于"o+"。"o{0,}"则等价于"o*"。
|
re{ n, m}
|
匹配 n 到 m 次由前面的正则表达式定义的片段,贪婪方式
|
a| b
|
匹配a或b
|
(re)
|
匹配括号内的表达式,也表示一个组
|
(?imx)
|
正则表达式包含三种可选标志:i, m, 或 x 。只影响括号中的区域。
|
(?-imx)
|
正则表达式关闭 i, m, 或 x 可选标志。只影响括号中的区域。
|
(?: re)
|
类似 (...), 但是不表示一个组
|
(?imx: re)
|
在括号中使用i, m, 或 x 可选标志
|
(?-imx: re)
|
在括号中不使用i, m, 或 x 可选标志
|
(?#...)
|
注释.
|
(?= re)
|
前向肯定界定符。如果所含正则表达式,以 ... 表示,在当前位置成功匹配时成功,否则失败。但一旦所含表达式已经尝试,匹配引擎根本没有提高;模式的剩余部分还要尝试界定符的右边。
|
(?! re)
|
前向否定界定符。与肯定界定符相反;当所含表达式不能在字符串当前位置匹配时成功。
|
(?> re)
|
匹配的独立模式,省去回溯。
|
\w
|
匹配数字字母下划线
|
\W
|
匹配非数字
非
字母
非
下划线
|
\s
|
匹配任意空白字符,等价于 [\t\n\r\f]。
|
\S
|
匹配任意非空字符
|
\d
|
匹配任意数字,等价于 [0-9]。
|
\D
|
匹配任意非数字
|
\A
|
匹配字符串开始
|
\Z
|
匹配字符串结束,如果是存在换行,只匹配到换行前的结束字符串。
|
\z
|
匹配字符串结束
|
\G
|
匹配最后匹配完成的位置。
|
\b
|
匹配一个单词边界,也就是指单词和空格间的位置。例如, 'er\b' 可以匹配"never" 中的 'er',但不能匹配 "verb" 中的 'er'。
|
\B
|
匹配非单词边界。'er\B' 能匹配 "verb" 中的 'er',但不能匹配 "never" 中的 'er'。
|
\n, \t, 等。
|
匹配一个换行符。匹配一个制表符, 等
|
\1...\9
|
匹配第n个分组的内容。
|
\10
|
匹配第n个分组的内容,如果它经匹配。否则指的是八进制字符码的表达式。
|
这些都是在正则表达式中,具有特殊意义的东西,那么遇到他们的时候就要注意了
先给个例子
这里要提醒一下,加r只能代表python中的原生字符,不能说是代表正则表达式的原生字符(所以这个例子加r没有任何作用)
匹配字符串'$数字'
import re
text = "apple price is $99,orange paice is $88"
ret = re.search('\$(\d+)',text) #在re中,$具有特殊的意思,所以需要对他进行转义,转义成普通字符串来进行匹配
print(ret.group())
>> $99
再来一个例子:
匹配text里的\c字符串
text = "apple \c"
ret = re.search('\\\\c',text)
print(ret.group())
\c
我们来好好解释一下为什么要有四个\\\\????(小朋友,你是不是有很多问号????)
那我们之前是不是说过正则表达式中的转义步骤:(那就一步一步是爪....)
第一步骤:先进行python转义
\\\\四个反斜杠是不是转义成两个反斜杠,此刻的两个反斜杠是字符串,在python中是不带有转义的意思了
如果还是不懂,我们来分析一下,
先把四个反斜杠平均拆成两份,也就是\\和\\
第一份反斜杠转义出来不就是这个反斜杠\字符
第二份反斜杠转义出来不也是这个反斜杠\字符
结果:两个反斜杠(注意此刻的反斜杠是字符串,在python中是不具有转义功能)
第二步骤:进行正则表达式里的转义
此刻只剩下'\\c'这个表达式了
那么两个反斜杠就要转义生成一个反斜杠字符串啦(此刻在正则表达式中这个反斜杠字符串不具有转义功能啦)
【注意注意:转义是分场合的,分为在python中和在正则表达式中】
最后结果就是‘\c’匹配这个字符串啦
当然还有一种写法:
text = "apple \c"
ret = re.search(r'\\c',text)
print(ret.group())
\c
这里为什么少了两个反斜杠???
因为r已经表明这个字符串在python中是原生字符串啦(即省略第一个步骤)