@poly Eu acho que isso também deve ter sido solicitado para C ++, mas não consigo encontrá-lo #
Michael Mrozek
1
Há uma tag std na pergunta, mas talvez você esteja interessado nos algoritmos de string do boost, que também incluem uma ampla variedade de algoritmos de substituição (inplace / copy, case sensitive / case insensitive, substitua first / last / all / n-th )
Há uma função para encontrar uma substring dentro de uma string ( find) e uma função para substituir um intervalo específico em uma string por outra string ( replace), para que você possa combiná-las para obter o efeito desejado:
Como eu o consertaria se a string original tivesse mais de uma instância de "$ name" e eu quisesse substituí-las.
Tom Leese
1
Por que não são frome topassaram por constreferência? O que sua função se fromnão existe? -1de mim por isso.
SBI
10
@sbi Corrigido, embora você pudesse tê-lo formulado como recomendações em vez de ataques - simplesmente não me ocorreu, eu raramente penso em usar conste se eu escrevesse um método utilitário como esse, eu o chamaria apenas se soubesse o substituição válida
Michael Mrozek
10
@ Michael: Bom, eu transformei meu voto negativo em voto positivo. Descartar consté desconsiderar uma das melhores ferramentas do C ++. Passar por constreferência deve ser o modo padrão para os parâmetros de função. (FTR, sem const, você não poderia mesmo passar strings literais para a sua função, porque você não pode temporários se ligam a não- constreferências Assim, a função não teria sequer fazer o que foi escrito para..)
SBI
19
Essa ainda é a única solução em 2018? Se sim, e qualquer comitê de C ++ estiver lendo isso, resolva-o. É embaraçoso. divida (string, string) e substitua (string, string) por favor!
Tenho certeza std::regex_replaceque não aceita a string do Qt.
BartoszKP
1
Você está certo. Ocorre que o QString fornece um método de substituição que aceita um QRexExp, permitindo o uso do material do Qt. Mas acho que a resposta atual pode ser corrigida substituindo stringpor string.toStdString().
24415 Tom
1
Ou apenas mudando Stringpara std::string, porque a pergunta não está relacionada ao Qt. Por favor, considere fazer isso - de bom grado aprovaremos sua resposta depois.
BartoszKP
5
A cadeia bruta permite escrever em R"(\$name)"vez de "\\$name".
precisa saber é o seguinte
2
Quanto isso será mais lento do que localizar / substituir sem considerar o tempo de construção do std :: regex?
jw_
18
std::stringtem um replacemétodo, é isso que você está procurando?
Sua chamada para subject.replace em ReplaceStringInPlace () está realmente modificando a string inplace?
Damian
Olhei brevemente a fonte e parece que ela usa semântica de movimento para mover a frente da string antiga para o lugar, para que não seja copiada, mas a nova peça inserida é copiada para a string antiga e a cauda da string antiga. é copiado no buffer redimensionado da string antiga. É possível que a string expanda tanto que todo o buffer subjacente seja realocado, mas se você substituir 1 para 1, como no exemplo dele, acho que ocorre "no local" ou sem copiar, mas se você expandir a string, apenas a primeira parte da cadeia antiga não é copiada e somente talvez então.
quer
6
Sim, você pode fazer isso, mas você precisa encontrar a posição da primeira string com o membro find () da string e, em seguida, substituir por seu membro replace ().
Ele chama repetidamente std::string::find()para localizar outras ocorrências da string pesquisada até std::string::find()que não encontre nada. Como std::string::find()retorna a posição da partida, não temos o problema de invalidar iteradores.
Você pode agrupar isso em uma função, mas esta solução de uma linha parece aceitável. O problema é que isso mudará apenas a primeira ocorrência; talvez você queira fazer um loop sobre ela, mas também permite inserir várias variáveis nessa string com o mesmo token ( %s)
Como o estilo, mas encontrou as cordas diferentes confundindo ^^str.replace(str.find("%s"), string("%s").size(), "Something");
Paul Würtz
3
Se todas as strings forem std :: string, você encontrará problemas estranhos com o corte de caracteres se estiver usando sizeof()porque se destina a strings C, não a C ++. A correção é usar o .size()método de classe de std::string.
wstring myString = L"Hello $$ this is an example. By $$.";
wstring search = L"$$";
wstring replace = L"Tom";for(int i = myString.find(search); i >=0; i = myString.find(search))
myString.replace(i, search.size(), replace);
Se você quiser fazer isso rapidamente, poderá usar uma abordagem de duas varreduras. Pseudo-código:
primeira análise. encontre quantos caracteres correspondentes.
expanda o comprimento da string.
segunda análise. Começa no final da string quando obtemos uma correspondência que substituímos; caso contrário, apenas copiamos os caracteres da primeira string.
Não tenho certeza se isso pode ser otimizado para algo no local.
E um exemplo de código C ++ 11, mas eu só procuro um caractere.
Agora estou aprendendo C ++, mas, editando parte do código publicado anteriormente, provavelmente usaria algo assim. Isso oferece a flexibilidade de substituir 1 ou várias instâncias e também permite especificar o ponto de partida.
Respostas:
Há uma função para encontrar uma substring dentro de uma string (
find
) e uma função para substituir um intervalo específico em uma string por outra string (replace
), para que você possa combiná-las para obter o efeito desejado:Em resposta a um comentário, acho
replaceAll
que provavelmente seria algo como isto:fonte
from
eto
passaram porconst
referência? O que sua função sefrom
não existe?-1
de mim por isso.const
e se eu escrevesse um método utilitário como esse, eu o chamaria apenas se soubesse o substituição válidaconst
é desconsiderar uma das melhores ferramentas do C ++. Passar porconst
referência deve ser o modo padrão para os parâmetros de função. (FTR, semconst
, você não poderia mesmo passar strings literais para a sua função, porque você não pode temporários se ligam a não-const
referências Assim, a função não teria sequer fazer o que foi escrito para..)Com o C ++ 11, você pode usar
std::regex
assim:A barra invertida dupla é necessária para escapar de um caractere de escape.
fonte
std::regex_replace
que não aceita a string do Qt.string
porstring.toStdString()
.String
parastd::string
, porque a pergunta não está relacionada ao Qt. Por favor, considere fazer isso - de bom grado aprovaremos sua resposta depois.R"(\$name)"
vez de"\\$name"
.std::string
tem umreplace
método, é isso que você está procurando?Você poderia tentar:
Ainda não tentei, basta ler a documentação em
find()
ereplace()
.fonte
Para que a nova string seja retornada, use isto:
Se você precisar de desempenho, aqui está uma função otimizada que modifica a sequência de entrada, ela não cria uma cópia da sequência:
Testes:
Resultado:
fonte
Sim, você pode fazer isso, mas você precisa encontrar a posição da primeira string com o membro find () da string e, em seguida, substituir por seu membro replace ().
Se você planeja usar a Biblioteca Padrão, deve adquirir uma cópia do livro A Biblioteca Padrão C ++, que cobre tudo isso muito bem.
fonte
Eu geralmente uso isso:
Ele chama repetidamente
std::string::find()
para localizar outras ocorrências da string pesquisada atéstd::string::find()
que não encontre nada. Comostd::string::find()
retorna a posição da partida, não temos o problema de invalidar iteradores.fonte
Isso soa como uma opção
string.replace(string.find("%s"), string("%s").size(), "Something");
Você pode agrupar isso em uma função, mas esta solução de uma linha parece aceitável. O problema é que isso mudará apenas a primeira ocorrência; talvez você queira fazer um loop sobre ela, mas também permite inserir várias variáveis nessa string com o mesmo token (
%s
)fonte
str.replace(str.find("%s"), string("%s").size(), "Something");
Se todas as strings forem std :: string, você encontrará problemas estranhos com o corte de caracteres se estiver usando
sizeof()
porque se destina a strings C, não a C ++. A correção é usar o.size()
método de classe destd::string
.Isso substitui o sHaystack inline - não é necessário fazer uma atribuição =.
Exemplo de uso:
fonte
fonte
Se você quiser fazer isso rapidamente, poderá usar uma abordagem de duas varreduras. Pseudo-código:
Não tenho certeza se isso pode ser otimizado para algo no local.
E um exemplo de código C ++ 11, mas eu só procuro um caractere.
fonte
fonte
Minha própria implementação, levando em consideração que a string precisa ser redimensionada apenas uma vez, e a substituição pode acontecer.
O uso pode ser, por exemplo, assim:
fonte
Agora estou aprendendo C ++, mas, editando parte do código publicado anteriormente, provavelmente usaria algo assim. Isso oferece a flexibilidade de substituir 1 ou várias instâncias e também permite especificar o ponto de partida.
fonte
Isso poderia ser ainda melhor para usar
fonte