在Python字符串中转义特殊字符

161

Python有没有可以用来转义字符串中特殊字符的函数?

例如,I'm "stuck" :\ 应该变成 I\'m \"stuck\" :\\


4
你认为什么是特殊字符? - pafcu
2
完全取决于您的上下文。通常,当您将它们放在字符串中时,这些字符是完全可以接受的。 - poke
可能是在Python中转义正则表达式字符串的重复问题。 - Jukka Suomela
2
这个问题最初并没有涉及到正则表达式,但是三年后的编辑中才加入了这一内容。由于我们已经有了一个很好的规范来转义正则表达式字符串,因此我将问题恢复到其原始含义,因为大多数答案也不是针对这种特殊情况的回应。 - poke
正如您当时所指出的,这个问题无法回答,因为“转义”和“特殊”都没有得到正确的定义。例如,应该让换行符保持原样吗?在它之前插入反斜杠?变成反斜杠后跟小写字母n?变成反斜杠后跟小写字母x,后跟零,后跟小写字母a?还是其他什么? - Karl Knechtel
相关:unicode-escapeshlex.quote - user202729
7个回答

256

使用re.escape函数。

>>> import re
>>> re.escape(r'\ a.*$')
'\\\\\\ a\\.\\*\\$'
>>> print(re.escape(r'\ a.*$'))
\\\ a\.\*\$
>>> re.escape('www.stackoverflow.com')
'www\\.stackoverflow\\.com'
>>> print(re.escape('www.stackoverflow.com'))
www\.stackoverflow\.com

重复一遍:

re.escape(string)

返回一个字符串,其中所有非字母数字字符都被反斜杠转义;如果您想匹配一个任意的文本字符串,该字符串可能包含正则表达式元字符,则此函数很有用。

从 Python 3.7 开始,re.escape() 只会转义那些对正则表达式操作有意义的字符。


2
你可以使用regex模块代替re。一个例子是regex.escape(pattern,string,special_only=True) - Lokinou
请注意,re.escape 会将例如换行符转换为反斜杠后跟换行符;相反,您可能希望得到反斜杠后跟小写字母 n。 - Karl Knechtel

23

我很惊讶没有人提到使用re.sub()来使用正则表达式:

import re
print re.sub(r'([\"])',    r'\\\1', 'it\'s "this"')  # it's \"this\"
print re.sub(r"([\'])",    r'\\\1', 'it\'s "this"')  # it\'s "this"
print re.sub(r'([\" \'])', r'\\\1', 'it\'s "this"')  # it\'s\ \"this\"

需要注意的重要事项:

  • 查找模式中,除了要包含您要查找的字符,还要包含\。 您将使用\来转义字符,因此您也需要对它进行转义
  • 查找模式周围加上括号,例如([\"]),以便替换 模式可以在其前面添加\时使用找到的字符。(这就是\1的作用:使用第一个括号分组的值。)
  • r'([\"])'中的r表示它是一个原始字符串。原始字符串使用不同的规则来转义反斜杠。 要将([\"])写成普通字符串,您需要将所有反斜杠都加倍并写成'([\\"])'。当您编写正则表达式时,原始字符串更友好。
  • 替换模式中,您需要转义\以将其与前置于替换组前面的反斜杠区分开来, 例如\1,因此为r'\\\1'。如果要将写为普通字符串,则需要'\\\\\\1',而没有人想要那样。

10

使用repr()[1:-1]。在这种情况下,双引号不需要转义。[-1:1]切片是为了去掉开头和结尾的单引号。

>>> x = raw_input()
I'm "stuck" :\
>>> print x
I'm "stuck" :\
>>> print repr(x)[1:-1]
I\'m "stuck" :\\

或者你只想转义一个短语以粘贴到程序中?如果是这样,请执行以下操作:

>>> raw_input()
I'm "stuck" :\
'I\'m "stuck" :\\'

3
如果字符串是Unicode编码,那么这种方法不起作用,因为会出现“u”,你需要运行repr(x)[2:-1] - Antoine Pelisse
在 Python3.4 中,所有字符串都是 Unicode,但不幸的是这个代码似乎完全没有用。相反,print(repr("I'm stuck")[1:-1]) 输出 I'm stuck - dantiston
@dantiston 这不是因为字符串都是Unicode,而是因为你的示例没有触发repr将单引号视为需要转义的情况。 - Karl Knechtel
1
有了七年的经验,我同意@KarlKnechtel的看法;这个答案只适用于特定情况,而不是转义特殊字符的一般情况。 - dantiston

3

正如上面提到的,答案取决于您的情况。如果您想为正则表达式转义一个字符串,则应使用re.escape()。但是,如果您想转义一组特定的字符,则可以使用此lambda函数:

>>> escape = lambda s, escapechar, specialchars: "".join(escapechar + c if c in specialchars or c == escapechar else c for c in s)
>>> s = raw_input()
I'm "stuck" :\
>>> print s
I'm "stuck" :\
>>> print escape(s, "\\", ['"'])
I'm \"stuck\" :\\

2
如果您只想替换一些字符,可以使用以下方法:
import re

print re.sub(r'([\.\\\+\*\?\[\^\]\$\(\)\{\}\!\<\>\|\:\-])', r'\\\1', "example string.")

0

使用 JSON:

import json
print(r"""(I'm "stuck" :\)""")               # (I'm "stuck" :\)
print(json.dumps(r"""(I'm "stuck" :\)"""))   # (I'm "stuck" :\)

将 JSON 转换为带转义字符的字符串

json.dumps(json.dumps(d))

0
注意:此答案是针对原问题编写的,原问题以一种通用的方式提出了“可以用于转义特殊字符”的问题,而没有指定这些字符将用于正则表达式,并且没有进一步指定需要转义哪些特殊字符。
为了转义任意一组“特殊字符”,您可以编写一个自定义函数,将每个特殊字符替换为转义变体。类似这样的东西:
def escapeSpecialCharacters ( text, characters ):
    for character in characters:
        text = text.replace( character, '\\' + character )
    return text

>>> escapeSpecialCharacters( 'I\'m "stuck" :\\', '\'"' )
'I\\\'m \\"stuck\\" :\\'
>>> print( _ )
I\'m \"stuck\" :\

4
如果反斜杠是“字符”之一,最好将其放在第一个! - steveha

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接