2

假设我在 Ruby 中有以下函数,它在每个新行按用户定义的空格数缩进一个字符串。

def reindent(str, numIndent)
    return str.gsub(/(.)^/m) { |m| $1 + ("    " * numIndent) }
end

我将如何使用 re 在 Python 中模仿这个函数?

我尝试了以下方法,但没有奏效。

def reindent(line, numIndent):
  return re.sub(r'(.)^', r'\1' + '    ' * numIndent, line, flags=re.MULTILINE)
4

2 回答 2

1

您应该知道,Matz 选择将/s修饰符 ( SINGLELINEor DOTALL) 重命名为 Ruby 的/m( MULTILINE) 修饰符(处理换行符是否被视为“任何字符” ),从而迷惑所有人.

相反,其他风格的/morMULTILINE修饰符(它决定是否匹配在行的开头/结尾而不是整个字符串的开头/结尾)在 Ruby 中根本不存在^$这些锚点总是 在行的开头/结尾匹配。

所以,要将你的代码从 Ruby 翻译成 Python,你需要做

def reindent(line, numIndent):
    return re.sub(r'(.)^', r'\1' + '    ' * numIndent, line, flags=re.DOTALL|re.MULTILINE)

如果您的目标是缩进除第一行之外的所有行(这就是这样做的),您可以简化正则表达式:

def reindent(line, numIndent):
    return re.sub(r'(?<!\A)^', '    ' * numIndent, line, flags=re.MULTILINE)

结果:

>>> s = "The following lines\nare indented,\naren't they?"
>>> print(reindent(s,1))
The following lines
    are indented,
    aren't they?
于 2013-09-18T06:31:45.290 回答
0

请改用相反的形式:

import re
def reindent(line, numIndent):
  return re.sub(r'^(.*)', '    ' * numIndent + r'\1', line, flags=re.MULTILINE)
print(reindent("abcdefghijkl\nmnopqrstu", 1))

输出:

    abcdefghijkl
    mnopqrstu
于 2013-09-18T06:36:23.040 回答