正则表达式子问题
好吧,我遇到了一个有点奇怪的问题,跟 re.sub 有关。
看看下面这段代码:
import re
str_to_be_subbed = r'somefile.exe -i <INPUT>'
some_str = r'C:\foobar'
s = re.sub(r'\<INPUT\>', some_str, str_to_be_subbed)
print s
我本以为它会给我:
somefile.exe -i C:\\foobar
但实际上它给了我:
somefile.exe -i C:♀oobar
我知道 \f 是一个转义字符,但即使我尝试这样做,应该可以转义特殊字符。即使我这样做:
print r'%s' % s
它还是给了我这个:
somefile.exe -i C:♀oobar
为什么会这样呢?有什么好的方法可以避免这个问题吗?
补充说明:
如果我查看 s 的值,它是:
'somefile.exe -i C:\x0coobar'
为什么 \f 变成了 \x0。真让人烦。
再补充:
还有一个问题,如果我把代码改成这样:
import re
import os
str_to_be_subbed = r'somefile.exe -i <INPUT>'
some_str = os.path.abspath(r'C:\foobar')
some_str
s = re.sub(r'\<INPUT\>', some_str, str_to_be_subbed)
print s
结果是:
>>> import re
>>> import os
>>> str_to_be_subbed = r'somefile.exe -i <INPUT>'
>>> some_str = os.path.abspath(r'C:\foobar')
>>> some_str
'C:\\foobar'
>>> s = re.sub(r'\<INPUT\>', some_str, str_to_be_subbed)
>>> print s
somefile.exe -i C:♀oobar
这又是为什么呢?因为 os.path.abspath 会转义 \'s。为什么 re.sub 还是会出错呢?
另外,这只是一个很小的例子,问题在一个比较老的应用程序中突然出现。我不能随便把它改成 string.replace,因为这样改的话可能要花一整天的时间。
我只是很好奇,为什么会出现这个问题。关于上面提到的情况。
4 个回答
Python文档中提到...
re.sub(pattern, repl, string, count=0, flags=0) 这个函数的作用是:它会在字符串中找到最左边的、不重叠的符合模式的部分,然后用你提供的替代内容来替换。如果找不到这个模式,字符串就会保持不变。替代内容可以是一个字符串,也可以是一个函数;如果是字符串的话,里面的反斜杠转义字符会被处理。也就是说,像\n会被转换成一个换行符,\r会被转换成回车符,其他不认识的转义字符,比如\j,就不会被处理。
这就是为什么它会返回'C:♀oobar'的原因。
但是如果我们把一个函数作为第二个参数传进去,它就不会处理任何反斜杠转义字符了。
所以可以试试下面的代码...
>>>import re
>>>str_to_be_subbed = r'somefile.exe -i <INPUT>'
>>>some_str = r'C:\foobar'
>>>s = re.sub(r'\<INPUT\>', lambda _:some_str, str_to_be_subbed)
>>>print s
somefile.exe -i c:\foobar
不要使用正则表达式:
print str_to_be_subbed.replace("<INPUT>",some_str)
正如文档中所说:
repl可以是一个字符串或者一个函数;如果它是字符串,那么其中的反斜杠转义字符会被处理。
\f
是一个叫做 换页符 的字符。把它转义一下就能正常使用了:
some_str = r'C:\\foobar'
还有一种解决办法:
s = re.sub(r'<INPUT>', some_str.encode("string_escape"), str_to_be_subbed)