如何在Python中注入转义序列

4
我需要在字符串中为某些字符(这里以双引号为例)放置转义序列。例如,如果我有一个字符串 "abra"cada"bra",我需要生成这个字符串:abra\"cada\"bra。但是,如果字符串已经具有我感兴趣的文字的转义字符(例如,在这个例子中是双引号) abra\"cada\"bra,我需要保持不变。
在Python中最简单的方法是什么?
(想法是将其写入由另一个实用程序读取的文本文件中。)

如果转义字符本身被转义,预期的输出是什么:abra\\"cada\\"bra - jfs
@J. F. Sebastian - 很好的问题!正则表达式回溯变得更加复杂。 - tdelaney
5个回答

2

最好先解码字符串,这样就不会有任何转义内容,然后再重新转义结果字符串。


1
您可以使用适当的负回溯断言在正则表达式中获取它:
import re

PAT = re.compile(r'(?<!\\)"')
txt1 = '"abra"cada"bra'
txt2 = '\\"abra\\"cada\\"bra'
print PAT.sub(r'\\"', txt1)
print PAT.sub(r'\\"', txt2)

这将确保即使引号是字符串的第一个字符(如上例),它也能正确工作。

哦天啊,之前的尝试留下了一些痕迹。我现在已经纠正了它。谢谢! - Bálint Aradi
当然,我完全同意这可能是更好的策略(我已经为你的答案点赞了 :-))。也许我会使用正则表达式来进行非转义和转义,这样就可以同时处理多个特殊字符(例如 ' 和 ")... - Bálint Aradi
1
为了允许动态指定转义序列:e,c ='\\"';print re.sub(r"(?<!{}){}".format(*map(re.escape,[e,c])), (e+c).encode('string-escape'), r'a"b\"c')相关问题链接 - jfs

1

像这样的东西

def esc_string(mystring, delim, esc_char='\\'):
    return (esc_char+delim).join([s[:-1] if s.endswith(esc_char) else s for s in mystring.split(delim)])

然后
print esc_string('abra"cada"bra', '"')
abra\"cada\"bra
print esc_string('abra\\"cada\\"bra', '"')
abra\"cada\"bra
print esc_string('"boundary test"', '"')
\"boundary test\"
print esc_string('\\"boundary test\\"', '"')
\"boundary test\"

1
假设\除了在某些字符(如'"')之前没有特殊含义,那么@chepner的建议首先执行反转义的操作可以被实现为:
def escape(text, char='"', escape="\\"):
    escaped_char = escape + char
    text = text.replace(escaped_char, char) # unescape
    return text.replace(char, escaped_char) # escape

输入

"abra"cada"bra\"
\"abra\"cada\"bra"
"abra\"cada"bra\"
abra\"cada\\"bra\"
abra\"cada\\\"bra\"

输出

\"abra\"cada\"bra\"
\"abra\"cada\"bra\"
\"abra\"cada\"bra\"
abra\"cada\\"bra\"
abra\"cada\\\"bra\"

0

Regular expressions will do it. This one says to match the " character if it is not preceded by a backslash. I used an 'r' at the front of the strings to tell python not to treat the '\' character specially and I had to put it in twice to tell the regular expression parser not to use it specially. Try help(re) for what the (?

import re
re.sub(r'(?<!\\)"', r'\"', 'abra"cada\\"bra')
# Returns 'abra\\"cada\\"bra'


你如何在一般情况下转义替换参数(OP说'"'只是一个例子)。考虑如果使用'1'而不是'"'会发生什么。 - jfs
@J.F. Sebastian - "(?<!...)" 部分是一个负向回顾(如果 \ 在我要查找的内容前面,则不匹配)。而 " 是我要查找的内容。我可以使用 [] 将 " 替换为一组字符:r'(?<!\\)["1x]' 将转义 " 1 和 x。 - tdelaney
我指的是 re.sub() 的第二个参数,其中 \1 具有特殊含义。使用单个 re.sub() 实现 escape(text, char) 很困难。 - jfs
棘手的部分是处理四个转义上下文:Python字符串文字,正则表达式模式,re.subrepl参数,最后是问题中的规则。 - jfs

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