【问题标题】:Using a single replacement operation replace all leading tabs with spaces使用单个替换操作将所有前导制表符替换为空格
【发布时间】:2016-08-19 11:58:44
【问题描述】:

在我的文本中,我想用两个空格替换所有前导制表符,但不理会非前导制表符。

例如:

a
\tb
\t\tc
\td\te
f\t\tg

("a\n\tb\n\t\tc\n\td\te\nf\t\tg")

应该变成:

a
  b
    c
  d\te
f\t\tg

("a\n b\n c\n d\te\nf\t\tg")

就我而言,我可以通过多次替换操作来做到这一点,重复次数与最大嵌套级别一样多,或者直到没有任何变化。

但不是也可以一次运行吗?

我尝试了但没有想出一些东西,我想出的最好的是环顾四周:

re.sub(r'(^|(?<=\t))\t', '  ', a, flags=re.MULTILINE)

哪个“仅”会导致一个错误的替换(fg 之间的第二个标签)。

现在可能根本不可能在一次运行中使用正则表达式,因为已经替换的部分无法再次匹配(或者更确切地说替换不会立即发生)并且你不能排序“ count" 在正则表达式中,在这种情况下,我希望看到一些关于原因的更详细的解释(只要这不会过多地转移到 [cs.se] 领域)。

我目前在 Python 中工作,但这可能适用于几乎任何类似的正则表达式实现。

【问题讨论】:

  • 为什么不只是.strip() 每行?
  • @jonrsharpe:我想替换 \ts,而不是删除它们。

标签: python regex


【解决方案1】:

您可以匹配行首的制表符,并在 re.sub 内使用 lambda 替换为双空格乘以匹配的长度:

import re
s = "a\n\tb\n\t\tc\n\td\te\nf\t\tg";
print(re.sub(r"^\t+", lambda m: "  "*len(m.group()), s, flags=re.M))

Python demo

【讨论】:

    【解决方案2】:

    也可以在没有正则表达式的情况下使用replace() 在一个衬里中执行此操作:

    >>> s = "a\n\tb\n\t\tc\n\td\te\nf\t\tg"
    >>> "\n".join(x.replace("\t","  ",len(x)-len(x.lstrip("\t"))) for x in s.split("\n"))
    'a\n  b\n    c\n  d\te\nf\t\tg'
    

    【讨论】:

      【解决方案3】:

      这有点疯狂,但它确实有效:

      "\n".join([ re.sub(r"^(\t+)"," "*(2*len(re.sub(r"^(\t+).*","\1",x))),x) for x in "a\n\tb\n\t\tc\n\td\te\nf\t\tg".splitlines() ])
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2015-11-01
        • 2020-03-11
        • 2013-06-14
        • 1970-01-01
        • 2010-12-23
        • 1970-01-01
        • 2016-05-02
        相关资源
        最近更新 更多