对 python 正则表达式字面字符串和模式字符串的一点思考

python 的正则表达式是与 Perl 语言类似的正则表达式匹配操作:

模式和被搜索的字符串既可以是 Unicode 字符串,也可以是 8 位字节串,但是 Unicode 字符串与 8 位字节串不能混用。

(即不能用字节串(ascii 就是字节串)模式匹配 Unicode 字符串,反之亦然;同理,替换操作时,替换字符串的类型也必须与所用的模式和搜索字符串的类型一致)

要匹配一个反斜杠字面值,用户可能必须写成 '\\\\' 来作为模式字符串,因为正则表达式必须为 \\,而每个反斜杠在普通 Python 字符串字面值中又必须表示为 \\。 而且还要注意,在 Python 的字符串字面值中使用的反斜杠如果有任何无效的转义序列,现在会触发 DeprecationWarning,但以后会改为 SyntaxError。

解决办法是对于正则表达式模式(patterns)使用 Python 的原始字符串表示法;在带有 'r' 前缀的字符串字面值中,反斜杠不必做任何特殊处理。 因此 r"\n" 表示包含 '\' 和 'n' 两个字符的字符串,而 "\n" 则表示只包含一个换行符的字符串。 (模式在 Python 代码中通常都使用原始字符串 'r' 表示法)

原始字符串标记:

>>> re.match(r"\W(.)\1\W", " ff ")
<re.Match object; span=(0, 4), match=' ff '>
>>> re.match("\\W(.)\\1\\W", " ff ")
<re.Match object; span=(0, 4), match=' ff '>

当需要匹配一个字符反斜杠,它必须在模式字符串中转义。在原始字符串记法,就是 r"\\",否则就必须用 "\\\\":

>>> re.match(r"\\", "\\")
<re.Match object; span=(0, 1), match='\\'>
>>> re.match("\\\\", "\\")
<re.Match object; span=(0, 1), match='\\'>

字面字符串、模式字符串、反斜杠、原始字符表示法 r :(反斜杠差一个编译级别)

正则表达式用反斜杠字符 ('\') 来转义特殊字符,但是由于单个 \ 不能和分界符引号 " 单独接触,即使有原始字符表示符 r 。

在字面字符串中:

r"\" 是错的,r"\\" == "\\\\",单个反斜杠只能写成 "\\",但是如果单个 \ 没有与分界符接触就没事,比如 r"\n"。

在模式字符串中:

r"\\" == "\\\\" ,这同样只表示一个反斜杠,单独的 "\\" 在模式字符中是错的,这是因为正则语法中每个带反斜杠的特殊符号原本都需要转义的,除非有原始字符表示符 r 。比如匹配 Unicode 词语的字符 r"\w" == "\\w",也就是说在一个正常的特殊字符 "\n" 在模式字符中写成 r"\n" == "\\n",而在字面字符串中只写成 "\n"。

模式字符串比字面字符串的反斜杠少一个编译级别:

也就是说正则的反斜杠是低一级的 ”未识别状态“,所以一个正常的 "\\" 在字面字符串中表示反斜杠,但在模式字符串中每个都是未识别的,所以变成 "\\\\",而原始字符 r 的作用就是使反斜杠提升一个 "识别级别"。但是由于字面字符串的 "识别级别" 是比模式字符串高一级的正常级别,所以 r"\n" 在字面字符串中表示一个单斜杠 "\\" 和一个字符 "n",但在模式字符串中只表示一个换行符。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

沐一 · 林

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值