Gostaria de usar a função .replace para substituir várias seqüências de caracteres.
Eu tenho atualmente
string.replace("condition1", "")
mas gostaria de ter algo como
string.replace("condition1", "").replace("condition2", "text")
embora isso não pareça uma boa sintaxe
qual é a maneira correta de fazer isso? tipo como no grep / regex você pode fazer \1
e \2
substituir os campos por certas strings de pesquisa
Respostas:
Aqui está um pequeno exemplo que deve funcionar com expressões regulares:
Por exemplo:
fonte
"spamham sha".replace("spam", "eggs").replace("sha","md5")
sendo"eggmd5m md5"
, em vez de"eggsham md5"
Você poderia apenas criar uma pequena função de loop.
onde
text
é a string completa edic
é um dicionário - cada definição é uma string que substituirá uma correspondência com o termo.Nota : no Python 3,
iteritems()
foi substituído poritems()
Cuidado: os dicionários Python não têm uma ordem confiável para iteração. Esta solução só resolve o seu problema se:
Por exemplo:
Saída possível # 1:
Saída possível # 2
Uma correção possível é usar um OrderedDict.
Resultado:
Cuidado # 2: Ineficiente se sua
text
corda for muito grande ou se houver muitos pares no dicionário.fonte
OrderedDict
- ou uma lista de duas tuplas.Por que não uma solução como essa?
fonte
Aqui está uma variante da primeira solução usando o método reduzir, caso você queira ser funcional. :)
a versão ainda melhor de martineau:
fonte
repls
uma sequência de tuplas e acabar com aiteritems()
chamada. ierepls = ('hello', 'goodbye'), ('world', 'earth')
ereduce(lambda a, kv: a.replace(*kv), repls, s)
. Também funcionaria inalterado no Python 3. #reduce
que foi removido .reduce
ainda existe, no entanto, foi feito parte dofunctools
módulo (consulte a documentação ) no Python 3; portanto, quando eu disse inalterado, quis dizer que o mesmo código poderia ser executado - embora seja certo que exigiria quereduce
fosseimport
editado, se necessário já que não é mais um built-in.Esta é apenas uma recapitulação mais concisa das ótimas respostas de FJ e MiniQuark. Tudo o que você precisa para obter várias substituições simultâneas de strings é a seguinte função:
Uso:
Se desejar, você pode criar suas próprias funções de substituição dedicadas a partir desta mais simples.
fonte
rep_dict = {"but": "mut", "mutton": "lamb"}
a string"button"
resulta em"mutton"
seu código, mas daria"lamb"
se as substituições fossem encadeadas, uma após a outra.Do you prefer cafe? No, I prefer cafe.
, o que não é desejável.Eu construí isso com base na excelente resposta dos FJs:
Uso de uma tomada:
Observe que, como a substituição é feita em apenas uma passagem, "café" muda para "chá", mas não volta para "café".
Se você precisar fazer a mesma substituição várias vezes, poderá criar uma função de substituição facilmente:
Melhorias:
Aproveitar! :-)
fonte
pattern.sub
espera uma função com apenas um parâmetro (o texto a ser substituído), portanto, a função precisa ter acessoreplace_dict
.re.M
permite substituições de várias linhas (isso está bem explicado no doc: docs.python.org/2/library/re.html#re.M ).Eu gostaria de propor o uso de modelos de string. Basta colocar a string a ser substituída em um dicionário e tudo está pronto! Exemplo de docs.python.org
fonte
substitute
gera uma exceção, portanto, tenha cuidado ao obter modelos dos usuários.No meu caso, eu precisava de uma simples substituição de chaves exclusivas por nomes, então pensei nisso:
fonte
i
coms
você teria um comportamento estranho.b = [ ['i', 'Z'], ['s', 'Y'] ]; for x,y in (b): a = a.replace(x, y)
Então, se você for cuidadoso ao solicitar seus pares de matrizes, pode garantir que não substitua () recursivamente.Iniciando
Python 3.8
e introduzindo expressões de atribuição (PEP 572) (:=
operador), podemos aplicar as substituições dentro de uma compreensão de lista:fonte
['The quick red fox jumps over the lazy dog', 'The quick red fox jumps over the quick dog']
. Mas a expressão de atribuição (text := text.replace
) também cria iterativamente novas versõestext
, modificando-a. Após a compreensão da lista, você pode usar atext
variável que contém o texto modificado.text
como uma linha, também pode usar[text := text.replace(a, b) for a, b in replacements][-1]
(observe o[-1]
), que extrai o último elemento da compreensão da lista; ou seja, a última versão dotext
.Aqui meus $ 0,02. Baseia-se na resposta de Andrew Clark, um pouco mais clara, e também abrange o caso em que uma sequência a ser substituída é uma substring de outra sequência a ser substituída (vitórias mais longas)
É nessa essência , sinta-se à vontade para modificá-la se você tiver alguma proposta.
fonte
Eu precisava de uma solução em que as seqüências a serem substituídas pudessem ser expressões regulares, por exemplo, para ajudar a normalizar um texto longo, substituindo vários caracteres de espaço em branco por um único. Com base em uma cadeia de respostas de outras pessoas, incluindo MiniQuark e mmj, é isso que eu criei:
Ele funciona para os exemplos dados em outras respostas, por exemplo:
O principal para mim é que você também pode usar expressões regulares, por exemplo, para substituir apenas palavras inteiras ou para normalizar o espaço em branco:
Se você quiser usar as teclas de dicionário como seqüências normais, poderá escapar delas antes de chamar multiple_replace usando, por exemplo, esta função:
A função a seguir pode ajudar a encontrar expressões regulares incorretas entre as chaves do seu dicionário (já que a mensagem de erro de multiple_replace não é muito reveladora):
Observe que ele não encadeia as substituições, mas as executa simultaneamente. Isso o torna mais eficiente sem restringir o que ele pode fazer. Para imitar o efeito do encadeamento, talvez seja necessário adicionar mais pares de substituição de cadeia e garantir a ordem esperada dos pares:
fonte
Aqui está uma amostra que é mais eficiente em seqüências longas com muitas substituições pequenas.
O objetivo é evitar muitas concatenações de seqüências longas. Cortamos a string de origem em fragmentos, substituindo alguns dos fragmentos à medida que formamos a lista e, em seguida, juntamos tudo novamente em uma string.
fonte
Você realmente não deve fazê-lo dessa maneira, mas acho muito legal:
Agora,
answer
é o resultado de todas as substituições, por sua veznovamente, isso é muito hacky e não é algo que você deveria usar regularmente. Mas é bom saber que você pode fazer algo assim, se precisar.
fonte
Eu estava lutando com esse problema também. Com muitas substituições, as expressões regulares lutam e são cerca de quatro vezes mais lentas que as repetidas
string.replace
(nas condições da minha experiência).Você deve absolutamente tentar usar a biblioteca Flashtext ( postagem no blog aqui , Github aqui ). No meu caso , foi um pouco mais do que duas ordens de magnitude mais rápido, de 1,8 sa 0,015 s (expressões regulares levaram 7,7 s) para cada documento.
É fácil encontrar exemplos de uso nos links acima, mas este é um exemplo de trabalho:
Note-se que Flashtext faz substituições numa única passagem (para evitar a -> b e b -> c traduzindo 'a' em 'c'). O texto em Flash também procura palavras inteiras (portanto, 'is' não corresponderá a 'th is '). Funciona bem se o seu objetivo for várias palavras (substituindo 'Isto é' por 'Olá').
fonte
<p>
por/n
. Eu tentei sua abordagem, mas com tags o flashtext não parece analisá-lo?<
e>
marcar o final de uma palavra (mas ser incluído na substituição)?Eu sinto que esta pergunta precisa de uma resposta lambda recursiva de linha única para completar, apenas porque. Então aí:
Uso:
Notas:
Nota: Como em todas as funções recursivas do python, uma profundidade de recursão muito grande (ou seja, dicionários de substituição muito grandes) resultará em um erro. Veja, por exemplo, aqui .
fonte
sys.getrecursionlimit()
é um par de 1000, máx. use um loop ou algo parecido ou tente simplificar as substituições.Não sei sobre velocidade, mas esta é a minha solução rápida para o dia-a-dia:
... mas eu gosto da resposta regex nº 1 acima. Nota - se um novo valor for uma substring de outro, a operação não será comutativa.
fonte
Você pode usar a
pandas
biblioteca e areplace
função que suporta correspondências exatas e substituições de regex. Por exemplo:E o texto modificado é:
Você pode encontrar um exemplo aqui . Observe que as substituições no texto são feitas com a ordem em que aparecem nas listas
fonte
Para substituir apenas um caractere, use o método
translate
estr.maketrans
é o meu favorito.tl; dr>
result_string = your_string.translate(str.maketrans(dict_mapping))
demonstração
fonte
A partir da resposta preciosa de Andrew, desenvolvi um script que carrega o dicionário de um arquivo e elabora todos os arquivos da pasta aberta para fazer as substituições. O script carrega os mapeamentos de um arquivo externo no qual você pode definir o separador. Sou iniciante, mas achei esse script muito útil ao fazer várias substituições em vários arquivos. Carregou um dicionário com mais de 1000 entradas em segundos. Não é elegante, mas funcionou para mim
fonte
esta é a minha solução para o problema. Usei-o em um chatbot para substituir as diferentes palavras de uma só vez.
isso vai se tornar
The cat hunts the dog
fonte
Outro exemplo: lista de entrada
A saída desejada seria
Código:
fonte
Ou apenas para um hack rápido:
fonte
Aqui está outra maneira de fazer isso com um dicionário:
fonte