【问题标题】:Compile replacement for Python's re.sub before the loop在循环之前编译替换 Python 的 re.sub
【发布时间】:2021-06-17 23:54:00
【问题描述】:

我有一些简单的代码可以使用 Python 的 re 替换子字符串:

pattern = re.compile(r'(--type-header )([^ ]*)')
for x in somelist:
    filename = '...'  # here is a filename
    switches = x.replace('alice', 'bob')  # simple string
    switches = pattern.sub(
        r'\1' + f'{os.path.dirname(filename)}/' + r'\2',
        switches
    )

我要替换的子字符串:

--type-header cond_enum_04.h

在 Linux/macOs 上,一切都像魅力一样。但在 Windows 上我得到:

re.error: 位置 16 处的错误转义 \c

循环进行了大约 250 次迭代(249 次迭代成功)。我怀疑这是 Windows 下循环中 re 的一个独特功能。有没有办法在进入循环之前编译替换?

【问题讨论】:

  • 如果问题出在搜索字符串中,您可以使用 re.escape() 使任意字符串免受任何误解 - 但对于替换字符串,它并没有做完全正确的事情,而且似乎没有任何等效的功能来处理这种情况。因此,您需要自己进行转义 - 将替换字符串中的所有反斜杠替换为双反斜杠,然后再将其传递给re.sub()
  • 只是推测,但问题可能与 Windows 路径的解析方式有关......所以我 @jasonharper 的建议可能有效,或者也可能使 filename 成为原始字符串,或者也许使用带有Path(filename).parent 之类的pathlib。完整的回溯可能会有所帮助,或者是 filename 值的实际示例。
  • @BrianLarsen,“使filename 成为原始字符串”并不是一件有意义的事情。 'r' 前缀仅影响字符串文字中反斜杠的解释,而不影响字符串变量中已经存在的反斜杠。 Pathlib 也无济于事,因为结果仍然是一个包含反斜杠的字符串。
  • @jasonharper,感谢您的反馈。也许Path(filename).parent.as_posix() 可能会提供所需的行为?我仍然认为对导致问题的文件名的实际值和完整的回溯有更多详细信息会有所帮助。
  • @BrianLarsen 您的建议可以解决问题。在上面的代码示例中,filename 包含 Windows 目录分隔符 `\`,被解释为正则表达式转义命令。您能否将您的评论转换为答案,以便我能够接受它。

标签: python python-re


【解决方案1】:

问题是由于 Windows 上的目录分隔符被解释为转义字符(请参阅here)。

一种可能的解决方案是使用pathlib 处理路径,并调用其.as_posix 方法以跨各种平台以一致的格式呈现路径字符串,然后适用于应用正则表达式。

所以在这种情况下,替换这个:

f'{os.path.dirname(filename)}/'

类似这样的:

f'{Path(filename).parent.as_posix()}/'

【讨论】:

    猜你喜欢
    • 2016-10-13
    • 1970-01-01
    • 2017-08-07
    • 1970-01-01
    • 2015-01-17
    • 2014-06-24
    • 1970-01-01
    • 1970-01-01
    • 2015-11-17
    相关资源
    最近更新 更多