在Python中替换前导文本

1 投票
2 回答
1626 浏览
提问于 2025-04-16 09:43

我在用Python 2.6,想把字符串开头的某些字符(在我的例子中是._$)替换成其他字符或字符串。因为我替换的字符串是一样的,所以我想出了这个方法:

def replaceLeadingCharacters(string, old, new = ''):
    t = string.lstrip(old)

    return new * (len(string) - len(t)) + t

这个方法看起来效果不错:

>>> replaceLeadingCharacters('._.!$XXX$._', '._$', 'Y')
'YYY!$XXX$._'
  • 有没有更好(更简单或更高效)的方法在Python中实现同样的效果?

  • 有没有办法用字符串而不是单个字符来实现这个效果?比如像str.replace()那样,一旦遇到不同于要替换的字符串就停止?现在我想出了这个:

    def replaceLeadingString(string, old, new = ''):
        n = 0
        o = 0
        s = len(old)
    
        while string.startswith(old, o):
            n += 1
            o += s
    
        return new * n + string[o:]
    

    我希望能有一种方法,不需要明确的循环来实现这个功能。

编辑:

有很多人用re模块来回答这个问题。我有几个疑问:

  • re作为替换时,速度是不是比str的方法慢很多?

  • 有没有简单的方法来正确地引用/转义将在正则表达式中使用的字符串?比如如果我想用re来做replaceLeadingCharacters,我该如何确保old变量的内容不会在^[old]+中搞混?我更希望有一个“黑箱”函数,不需要用户关注他们提供的字符列表。

2 个回答

1
re.sub(r'^[._$]+', lambda m: 'Y' * m.end(0), '._.!$XXX$._')

不过在我看来,你的第一个解决方案已经很好了。

1

你的 replaceLeadingCharacters() 方法看起来没问题。

这里有一个 replaceLeadingString() 的实现,它使用了 re 模块(没有使用 while 循环):

#!/usr/bin/env python
import re

def lreplace(s, old, new):
    """Return a copy of string `s` with leading occurrences of
    substring `old` replaced by `new`.

    >>> lreplace('abcabcdefabc', 'abc', 'X')
    'XXdefabc'
    >>> lreplace('_abc', 'abc', 'X')
    '_abc'
    """
    return re.sub(r'^(?:%s)+' % re.escape(old),
                  lambda m: new * (m.end() / len(old)),
                  s)

用它来替代字符串方法时,速度是不是明显慢很多?

别猜,直接测一下在你预期的输入下的表现。

有没有简单的方法可以正确地对将在正则表达式中使用的字符串进行引用/转义?

re.escape()

撰写回答