Python re.sub()在多行字符串上失败

Python re.sub()在多行字符串上失败,python,regex,python-3.6,multiline,Python,Regex,Python 3.6,Multiline,我有一个脚本的一部分,看起来像是这样的 import re, sys print(sys.version) # so you can see my Python version repl = ( "use bravo\\api\\resources\\usersResource;\n" "use bravo\\api\\resources\\groupsResource;\n" "use bravo\\api\\resources\\bandsResource;\n"

我有一个脚本的一部分,看起来像是这样的

import re, sys
print(sys.version) # so you can see my Python version

repl = (
    "use bravo\\api\\resources\\usersResource;\n"
    "use bravo\\api\\resources\\groupsResource;\n"
    "use bravo\\api\\resources\\bandsResource;\n"
    "use bravo\\api\\resources\\setlistsResource;\n"
    "use bravo\\api\\resources\\songsResource;"
)

pattern = r'\{\{\$use_table_resources\}\}'
string = "{{$use_table_resources}}"

re.sub(pattern, repl, string)
无论何时运行它,都会得到以下输出和错误:

3.6.2 |Anaconda, Inc.| (default, Sep 19 2017, 08:03:39) [MSC v.1900 64 bit (AMD64)]
Traceback (most recent call last):
  File "test.py", line 15, in <module>
    re.sub(pattern, repl, string)
  File "C:\ProgramData\Anaconda3\lib\re.py", line 191, in sub
    return _compile(pattern, flags).sub(repl, string, count)
  File "C:\ProgramData\Anaconda3\lib\re.py", line 326, in _subx
    template = _compile_repl(template, pattern)
  File "C:\ProgramData\Anaconda3\lib\re.py", line 317, in _compile_repl
    return sre_parse.parse_template(repl, pattern)
  File "C:\ProgramData\Anaconda3\lib\sre_parse.py", line 904, in parse_template
    raise s.error("missing <")
sre_constants.error: missing < at position 64 (line 2, column 26)
有时候,当我将repl替换字符串变短时,这会起作用,但我真的无法理解。据《华尔街日报》报道,据我所知,我是在他们的约束下工作的

我知道这个简单的例子不能证明使用regex是合理的,但是这段代码是从一个更大的软件中提取出来的。我不需要任何答案告诉我正则表达式是错误的方法,因为这实际上是我能产生的最简单的仍然重现问题的例子。还有更复杂的例子,我需要正则表达式来完成它的工作

无论如何,我认为问题出在替换字符串的内容上,尽管听起来很奇怪。当我使用较短的替换字符串时,我不会遇到此错误


非常感谢您的指点。这可能是一个非常微小和愚蠢的问题,但我已经重复了几次,我找不到它。

替换字符串中没有足够的转义,因此正则表达式引擎将反斜杠解释为捕获组的开始,如经典的r\1或\\1,没有原始前缀

您可以在每个字符串之前添加原始前缀,但我更愿意使用这样的多行原始字符串,以便于阅读:

repl = r"""use bravo\\api\\resources\\usersResource;
use bravo\\api\\resources\\groupsResource;
use bravo\\api\\resources\\bandsResource;
use bravo\\api\\resources\\setlistsResource;
use bravo\\api\\resources\\songsResource;
"""
然后,生成的替换是

use bravo\api\resources\usersResource;
use bravo\api\resources\groupsResource;
use bravo\api\resources\bandsResource;
use bravo\api\resources\setlistsResource;
use bravo\api\resources\songsResource;
现在,在不更改输入的情况下:

像re.subpattern、re.escaperepl、string那样使用re.escape并不能很好地工作,因为空格和行尾也会被转义

但您可以这样做,因为您知道唯一有问题的字符是反斜杠:

re.sub(pattern, repl.replace("\\",r"\\"), string)

它用双反斜杠替换反斜杠,输出相同

您知道一种简单的方法来避免替换吗?我程序其余部分的替换文本是从另一个文本源生成的。非常感谢,先生!我已经追了这只兔子差不多一整天了不客气。这比我自己预期的时间要长。该死的正则表达式: