看起来像后向引用被视为编码char

时间:2017-01-27 07:03:43

标签: regex python-2.7

from urllib import quote_plus
import re
mac = "00:aa:aa:aa:aa:aa"
path = r"\api\{mac}\test"
print quote_plus(mac)
print(re.sub("(.*?)" + "{mac}"  + "(.*)", "\\1" + quote_plus(mac)+ "\\2", path))

这给了我回复 @%3Aaa%3Aaa%3Aaa%3Aaa%3Aaa\test

但如果我将mac更改为aa:aa:aa:aa:aa:aa,那么我会收到预期的回复 \api\aa%3Aaa%3Aaa%3Aaa%3Aaa%3Aaa\test

任何想法这里发生了什么以及如何解决这个问题。

2 个答案:

答案 0 :(得分:3)

如果您想修复代码,您只需将"\\1"替换为"\\g<1>"(明确的反向引用)。

替换模式(连接后)在开头包含\100,实际上是@的八进制表示。

请参阅Python demo

有关明确的反向引用,请参阅Python re help

  

在字符串型 repl 参数中,除了上面描述的字符转义和反向引用外,\g<name>将使用由名为name的组匹配的子字符串,由{{ 1}}语法。 (?P<name>...)使用相应的组号;因此,\g<number>相当于\g<2>,但在\2等替换中并不含糊。 \g<2>0将被解释为对第20组的引用,而不是对第2组的引用,后跟文字字符\20。反向引用'0'替换为RE匹配的整个子字符串。

答案 1 :(得分:2)

为什么使用正则表达式?您可以使用字符串替换来执行此操作:

from urllib import quote_plus

mac = "00:aa:aa:aa:aa:aa"
mac2 = "aa:aa:aa:aa:aa:aa"
path = r"\api\{}\test"
print path.format(quote_plus(mac))
print path.format(quote_plus(mac2))

输出:

\api\00%3Aaa%3Aaa%3Aaa%3Aaa%3Aaa\test
\api\aa%3Aaa%3Aaa%3Aaa%3Aaa%3Aaa\test

如果要使用变量名格式化。

from urllib import quote_plus

mac = "00:aa:aa:aa:aa:aa"
mac2 = "aa:aa:aa:aa:aa:aa"
path = r"\api\{mac}\test"
print path.format(mac=quote_plus(mac))
print path.format(mac=quote_plus(mac2))