Замена начального текста в Python - PullRequest
1 голос
/ 10 января 2011

Я использую 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.У меня есть пара вопросов / проблем с ним:

  • Разве это не значительно медленнее, чем str методы, используемые в качестве замены для них?

  • Есть ли простой способ правильно заключать в кавычки / экранировать строки, которые будут использоваться в регулярном выражении?Например, если бы я хотел использовать re для replaceLeadingCharacters, как бы я гарантировал, что содержимое переменной old не испортит все в ^[old]+?Я предпочел бы иметь функцию «черного ящика», которая не требует от пользователей обращать внимание на список символов, которые они предоставляют.

Ответы [ 2 ]

1 голос
/ 10 января 2011

Ваш 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)

Разве это не значительно медленнее, чем методы str, когда они используются вместо них?

Не угадайте.Измерьте его для ожидаемого ввода.

Существует ли простой способ правильно заключать в кавычки / экранировать строки, которые будут использоваться в регулярном выражении?

re.escape()

1 голос
/ 10 января 2011
re.sub(r'^[._$]+', lambda m: 'Y' * m.end(0), '._.!$XXX$._')

Но ИМХО, ваше первое решение достаточно хорошее.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...