我对正则表达式中的反斜杠感到困惑.在正则表达式中,a \具有特殊含义,例如,\d表示十进制数字.如果在反斜杠前添加反斜杠,则此特殊含义会丢失.在正则表达式中,人们可以阅读:
也许最重要的元字符是反斜杠,
\.与Python字符串文字一样,反斜杠后面可以跟各种字符,以指示各种特殊序列.它也用于转义所有元字符,因此您仍然可以在模式中匹配它们; 例如,如果你需要匹配一个[或者\,你可以在它们前面加一个反斜杠来删除它们的特殊含义:\[或者\\.
所以print(re.search('\d', '\d'))给出None因为\d匹配任何十进制数字,但没有\d.
我现在期望print(re.search('\\d', '\d'))匹配,\d但答案仍然是None.
仅print(re.search('\\\d', '\d'))给出输出<_sre.SRE_Match object; span=(0, 2), match='\\d'>.
有人有解释吗?
Tom*_*zes 20
混淆是因为反斜杠字符\在两个不同的级别用作转义.首先,Python解释器本身\在re模块看到你的字符串之前执行替换.例如,\n转换为换行符,\t转换为制表符等.要获得实际\角色,您也可以将其转义,因此只\\需要一个\字符.如果后面的字符\不是可识别的转义字符,那么它将\被视为任何其他字符并通过,但我不建议依赖于此.相反,总是\通过加倍来逃避你的角色,即\\.
如果你想看看Python如何扩展你的字符串转义,只需打印出字符串.例如:
s = 'a\\b\tc'
print(s)
Run Code Online (Sandbox Code Playgroud)
如果s是聚合数据类型的一部分,例如列表或元组,并且如果打印该聚合,Python将用单引号括起该字符串并包含\转义(以规范形式),因此请注意字符串的方式正在印刷.如果您只是在解释器中键入带引号的字符串,它也会将其显示在带有'\'转义符的引号中.
一旦你知道你的字符串是如何被编码的,你就可以考虑\模块将用它做什么.例如,如果要re在传递给\模块的字符串中转义,则需要传递re给\\,这意味着您需要re在引用的Python字符串中使用.Python的字符串将结束与\\\\和\\模块将其视为一个单一的文字re字符.
\在Python字符串中包含字符的另一种方法是使用原始字符串,例如\相当于r'a\b'.
在对search()的调用中,正则表达式之前的r字符指定正则表达式是原始字符串.这允许反斜杠在正则表达式中用作常规字符,而不是在转义字符序列中.让我解释 ...
在re模块的搜索方法处理传递给它的字符串之前,Python解释器对字符串进行初始传递.如果字符串中存在反斜杠,则Python解释器必须确定每个是否是Python转义序列的一部分(例如\n或\ t).
注意:此时Python并不关心'\'是否是正则表达式元字符.
如果"\"之后是一个公认的Python转义字符(T,N,等),然后将反斜线和转义字符被替换为实际Unicode或8位字符.例如,'\ t'将替换为选项卡的ASCII字符.否则它被传递并解释为'\'字符.
考虑以下.
>>> s = '\t'
>>> print ("[" + s + "]")
>>> [ ] // an actual tab character after preprocessing
>>> s = '\d'
>>> print ("[" + s + "]")
>>> [\d] // '\d' after preprocessing
Run Code Online (Sandbox Code Playgroud)
有时我们希望在字符串中包含一个包含'\'的字符序列,而不会被Python解释为转义序列.要做到这一点,我们用'\'来逃避'\'.现在,当Python看到'\'时,它会用一个'\'字符替换两个反斜杠.
>>> s = '\\t'
>>> print ("[" + s + "]")
>>> [\t] // '\t' after preprocessing
Run Code Online (Sandbox Code Playgroud)
在Python解释器对两个字符串进行传递之后,它们将被传递给re模块的搜索方法.搜索方法解析正则表达式字符串以标识正则表达式的元字符.
现在'\'也是一个特殊的正则表达式元字符,并且被解释为一个UNLESS,它在执行re search()方法时被转义.
考虑以下电话.
>>> match = re.search('a\\t','a\\t') //Match is None
Run Code Online (Sandbox Code Playgroud)
这里匹配是None.为什么?让我们看看Python解释器传递后的字符串.
String 1: 'a\t'
String 2: 'a\t'
Run Code Online (Sandbox Code Playgroud)
那么为什么匹配等于None?当search()解释String 1时,由于它是正则表达式,因此反斜杠被解释为元字符,而不是普通字符.但是,字符串2中的反斜杠不在正则表达式中,并且已由Python解释器处理,因此它被解释为普通字符.
所以search()方法在字符串'a\t'中寻找'a escape-t',它们不匹配.
为了解决这个问题,我们可以告诉search()方法不要将'\'解释为元字符.我们可以通过逃避它来做到这一点.
考虑以下电话.
>>> match = re.search('a\\\\t','a\\t') // Match contains 'a\t'
Run Code Online (Sandbox Code Playgroud)
再次,让我们看看Python解释器传递后的字符串.
String 1: 'a\\t'
String 2: 'a\t'
Run Code Online (Sandbox Code Playgroud)
现在,当search()方法处理正则表达式时,它会看到第二个反斜杠被第一个反斜杠转义,不应该被视为元字符.因此,它将字符串解释为'a\t',它与String 2匹配.
将search()视为'\'作为字符的另一种方法是在正则表达式之前放置一个r.这告诉Python解释器不要预处理字符串.
考虑一下.
>>> match = re.search(r'a\\t','a\\t') // match contains 'a\t'
Run Code Online (Sandbox Code Playgroud)
这里的Python解释器不会修改第一个字符串,但会处理第二个字符串.传递给search()的字符串是:
String 1: 'a\\t'
String 2: 'a\t'
Run Code Online (Sandbox Code Playgroud)
与前面的示例一样,搜索将'\'解释为单个字符'\'而不是元字符,因此与字符串2匹配.
Python 自己的字符串解析(部分)会妨碍您。
如果您想查看re所见,请键入
print '\d'
print '\\d'
print '\\\d'
Run Code Online (Sandbox Code Playgroud)
在 Python 命令提示符下。您可以看到\d与\\d两个结果\d,后者由Python串分析器被照顾。
如果您想避免这些麻烦,请按照re 模块文档的建议使用原始字符串:r'\\d'将导致\\dRE 模块看到。
| 归档时间: |
|
| 查看次数: |
24473 次 |
| 最近记录: |