对正则表达式中的反斜杠感到困惑[重复]
- 2025-01-21 09:01:00
- admin 原创
- 74
问题描述:
我对正则表达式中的反斜杠感到困惑。在正则表达式中,a`具有特殊含义,例如
d`表示十进制数字。如果在反斜杠前面添加反斜杠,则此特殊含义会丢失。在regex-howto中,可以阅读:
也许最重要的元字符是反斜杠
。与 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'>
。
有人可以解释一下吗?
解决方案 1:
造成混淆的原因是反斜杠字符在两个不同级别用作转义符。首先,Python 解释器本身在模块看到字符串
之前会执行替换re
。例如,`转换为换行符,
转换为制表符等。要获取实际
`字符,也可以对其进行转义,因此\
会给出单个字符。如果跟在后面的字符
不是可识别的转义符,则将像其他字符一样处理并传递,但我不建议依赖这一点。相反,请始终
通过加倍字符来转义字符,即\
。
如果你想看看 Python 如何扩展字符串转义,只需打印出字符串即可。例如:
s = 'a\\b c'
print(s)
如果s
是聚合数据类型的一部分,例如列表或元组,并且如果您打印该聚合,Python 会将字符串括在单引号中并包含转义符(以规范形式),因此请注意字符串的打印方式。如果您只是在解释器中输入带引号的字符串,它也会将其括在带转义符的引号中
。
一旦你知道如何对字符串进行编码,你就可以考虑re
模块将如何处理它。例如,如果你想在传递给`re`模块的字符串中进行转义,你需要传递`\`给`re`,这意味着你需要`\\`在引用的 Python 字符串中使用 。Python 字符串将以 结尾`\`,`re`模块会将其视为单个文字
字符。
在 Python 字符串中包含字符的另一种方法`是使用原始字符串,例如
r'a'相当于
"a\b"`。
解决方案 2:
在对 search() 的调用中,正则表达式前面的 r 字符指定正则表达式是原始字符串。这允许在正则表达式中将反斜杠用作正则字符,而不是字符转义序列。让我解释一下...
在 re 模块的搜索方法处理传递给它的字符串之前,Python 解释器会对该字符串进行初始传递。如果字符串中存在反斜杠,Python 解释器必须确定每个反斜杠是否是 Python 转义序列的一部分(例如 \n 或 \t)。
注意:此时 Python 并不关心 '\' 是否是正则表达式元字符。
如果 '\' 后面跟着可识别的 Python 转义字符(t、n 等),则反斜杠和转义字符将被替换为实际的 Unicode 或 8 位字符。例如,'\t' 将被替换为制表符的 ASCII 字符。否则,它将被传递并解释为 '\' 字符。
请考虑以下情况。
>>> s = ' '
>>> print ("[" + s + "]")
>>> [ ] // an actual tab character after preprocessing
>>> s = 'd'
>>> print ("[" + s + "]")
>>> [d] // 'd' after preprocessing
有时我们希望在字符串中包含包含“\”的字符序列,但又不希望 Python 将其解释为转义序列。为此,我们将“\”转义为“\”。现在,当 Python 看到“\”时,它会将两个反斜杠替换为一个“\”字符。
>>> s = '\\t'
>>> print ("[" + s + "]")
>>> [ ] // ' ' after preprocessing
Python 解释器处理完这两个字符串后,会将它们传递给 re 模块的 search 方法。search 方法会解析正则表达式字符串,以识别正则表达式的元字符。
现在 '\' 也是一个特殊的正则表达式元字符,并且被解释为一个,除非它在执行 re search() 方法时被转义。
考虑以下调用。
>>> match = re.search('a\\t','a\\t') //Match is None
这里,match 为 None。为什么?让我们看看 Python 解释器传递后的字符串。
String 1: 'a '
String 2: 'a '
那么为什么 match 等于 None 呢?当 search() 解释字符串 1 时,由于它是一个正则表达式,所以反斜杠被解释为元字符,而不是普通字符。然而,字符串 2 中的反斜杠不在正则表达式中,并且已经被 Python 解释器处理过,因此它被解释为普通字符。
因此 search() 方法在字符串“a\t”中寻找不匹配的“a escape-t”。
为了解决这个问题,我们可以告诉 search() 方法不要将 '\' 解释为元字符。我们可以通过转义来实现这一点。
考虑以下调用。
>>> match = re.search('a\\\\t','a\\t') // Match contains 'a '
再次,让我们看一下 Python 解释器执行完毕后的字符串。
String 1: 'a\\t'
String 2: 'a '
现在,当 search() 方法处理正则表达式时,它发现第二个反斜杠被第一个反斜杠转义,因此不应被视为元字符。因此,它将字符串解释为 'a\t',与字符串 2 匹配。
让 search() 将 '\' 视为字符的另一种方法是在正则表达式前放置一个 r。这会告诉 Python 解释器不要预处理该字符串。
考虑一下。
>>> match = re.search(r'a\\t','a\\t') // match contains 'a '
这里 Python 解释器不修改第一个字符串,但会处理第二个字符串。传递给 search() 的字符串是:
String 1: 'a\\t'
String 2: 'a '
与前面的示例一样,搜索将“\”解释为单个字符“\”而不是元字符,因此与字符串 2 匹配。
解决方案 3:
Python 自身的字符串解析(部分)妨碍了你。
如果你想看看re
看到的内容,请输入
print 'd'
print '\\d'
print '\\d'
在 Python 命令提示符下。您会看到d
和\d
都导致d
,后者由 Python 字符串解析器处理。
如果您想避免这些麻烦,请按照re 模块文档的建议使用原始字符串:r'\d'
将导致\d
RE 模块看到。