Jaki jest skuteczny sposób na zastąpienie wszystkich wystąpień postaci inną postacią std::string
?
c++
algorithm
str-replace
stdstring
big-z
źródło
źródło
std::string
to pojemnik zaprojektowany specjalnie do pracy z sekwencjami znaków. linkstd::string::replace()
zamiaststd::replace()
! „x” (char
) jest domyślnie rzutowane nasize_t
[wartość 120], dlatego cały ciąg lub jego część zostanie wypełniona 120 kopiami „y”.Pomyślałem, że wrzucę również rozwiązanie doładowania :
źródło
-I
flag dla kompilatora, aby mógł on znaleźć biblioteki Boost w twoim systemie. Być może najpierw musisz go zainstalować.Pytanie koncentruje się na
character
wymianie, ale ponieważ uznałem tę stronę za bardzo przydatną (szczególnie uwagę Konrada ), chciałbym udostępnić tę bardziej uogólnioną implementację, która pozwala również poradzić sobie zsubstrings
:Stosowanie:
Wyjścia:
EDYTOWAĆ:
Powyższe można zaimplementować w bardziej odpowiedni sposób, w przypadku gdy wydajność ma znaczenie, zwracając nic (
void
) i wykonując zmiany bezpośrednio na łańcuchustr
podanym jako argument, przekazywany przez adres zamiast wartości . Pozwoliłoby to uniknąć niepotrzebnej i kosztownej kopii oryginalnego ciągu, zwracając jednocześnie wynik. Twoje połączenie, a następnie ...Kod :
Mam nadzieję, że będzie to pomocne dla niektórych innych ...
źródło
from
łańcuch jest pusty, w przeciwnym razie powstanie nieskończona pętla.Wyobraź sobie duży binarny obiekt blob, w którym wszystkie bajty 0x00 zostaną zastąpione przez „\ 1 \ x30”, a wszystkie bajty 0x01 przez „\ 1 \ x31”, ponieważ protokół transportowy nie zezwala na bajty \ 0.
W przypadkach, gdy:
dostarczone rozwiązania nie mogą być zastosowane (ponieważ zastępują tylko pojedyncze znaki) lub mają problem z wydajnością, ponieważ wywoływałyby ciąg :: zamień kilka razy, co generuje kopie rozmiaru obiektu blob w kółko. (Nie znam rozwiązania wspomagającego, może z tej perspektywy jest OK)
To jeden spacery wzdłuż wszystkich zdarzeń w ciągu źródłowym i buduje nowy kawałek po kawałku ciąg raz :
źródło
Proste wyszukiwanie i zamiana dla jednej postaci wyglądałoby mniej więcej tak:
s.replace(s.find("x"), 1, "y")
Aby to zrobić dla całego łańcucha, najłatwiej byłoby zapętlić, dopóki nie
s.find
zaczniesz powracaćnpos
. Przypuszczam, że mógłbyś złapać równieżrange_error
wyjście z pętli, ale to trochę brzydkie.źródło
{
postać. Nie wiem, co to jest „podwójny aparat ortodontyczny”. Być może masz problem z czcionkami?Jeśli chcesz zastąpić więcej niż jedną postać i masz do czynienia tylko z tym
std::string
, ten fragment kodu będzie działał, zastępując sNeedle w sHaystack sReplace, a sNeedle i sReplace nie muszą być tego samego rozmiaru. Ta procedura wykorzystuje pętlę while do zastąpienia wszystkich wystąpień, a nie tylko pierwszego znalezionego od lewej do prawej.źródło
find
dwa razy telefon. Zastanów się, czy ten wynik nie jest zmienną temp.Jak sugerował Kirill, albo zastosuj metodę replace, albo iteruj wzdłuż łańcucha, zastępując każdy znak niezależnie.
Alternatywnie możesz użyć
find
metody lub wfind_first_of
zależności od tego, co musisz zrobić. Żadne z tych rozwiązań nie wykona zadania za jednym razem, ale z kilkoma dodatkowymi wierszami kodu powinieneś sprawić, by działały dla Ciebie. :-)źródło
źródło
word
jest długi, może być dużo narzutu podczas wywoływania funkcji. Można zoptymalizować ten przekazującword
,target
ireplacement
jako const odniesień.Co z Abseil StrReplaceAll ? Z pliku nagłówka:
źródło
Stara szkoła :-)
Wynik:
źródło
To działa! Użyłem czegoś podobnego do tego w aplikacji księgarni, w której inwentarz był przechowywany w pliku CSV (np. Plik .dat). Ale w przypadku pojedynczego znaku, co oznacza, że zamiennik jest tylko jednym znakiem, np. „|”, Musi być w cudzysłowie „|” aby nie wyrzucić niepoprawnej stałej const char.
Nietypowo używam obecnie CentOS, więc moja wersja kompilatora jest poniżej. Wersja C ++ (g ++), domyślnie C ++ 98:
źródło
Jeśli chcesz użyć
std::string
s, możesz użyć funkcji tej przykładowej aplikacji bezstrsub
zmian lub zaktualizować ją, jeśli chcesz, aby przyjmowała inny typ lub zestaw parametrów, aby osiągnąć mniej więcej ten sam cel. Zasadniczo używa właściwości i funkcjonalności,std::string
aby szybko usunąć dopasowany zestaw znaków i wstawić żądane znaki bezpośrednio w ciągustd::string
. Za każdym razem, gdy wykonuje tę operację zastępowania, offset jest aktualizowany, jeśli nadal może znaleźć pasujące znaki do zastąpienia, a jeśli nie może tego zrobić z powodu niczego więcej do zastąpienia, zwraca ciąg znaków w stanie z ostatniej aktualizacji.Jeśli nie chcesz polegać na używaniu
std::string
s jako parametrów, aby zamiast tego przekazywać ciągi w stylu C, możesz zobaczyć zaktualizowaną próbkę poniżej:źródło
W prostych sytuacjach działa to całkiem dobrze bez użycia innej biblioteki niż std :: string (która jest już w użyciu).
Zamień wszystkie wystąpienia znaku a na znak b w some_string :
Jeśli ciąg jest duży lub wiele wezwań do zastąpienia jest problemem, możesz zastosować technikę wymienioną w tej odpowiedzi: https://stackoverflow.com/a/29752943/3622300
źródło
oto rozwiązanie, które rzuciłem, w maksymalnym duchu DRI. przeszuka sNeedle w sHaystack i zastąpi go sReplace, nTimes jeśli nie jest 0, w przeciwnym razie wszystkie wystąpienia sNeedle. nie będzie wyszukiwać ponownie w zastąpionym tekście.
źródło