¿Cómo encontrar y reemplazar una cadena?

Si s es std::string , ¿hay alguna función como la siguiente?

 s.replace("text to replace", "new text"); 

Pruebe una combinación de std::string::find y std::string::replace .

Esto consigue la posición:

 size_t f = s.find("text to replace"); 

Y esto reemplaza la primera ocurrencia:

 s.replace(f, std::string("text to replace").length(), "new text"); 

Ahora puede simplemente crear una función para su conveniencia:

 std::string replaceFirstOccurrence(std::string& s, const std::string& toReplace, const std::string& replaceWith) { std::size_t pos = s.find(toReplace); if (pos == std::string::npos) return s; return s.replace(pos, toReplace.length(), replaceWith); } 

¿Realmente necesitamos una biblioteca de Boost para una tarea aparentemente tan simple?

Para reemplazar todas las ocurrencias de una subcadena use esta función:

 std::string ReplaceString(std::string subject, const std::string& search, const std::string& replace) { size_t pos = 0; while ((pos = subject.find(search, pos)) != std::string::npos) { subject.replace(pos, search.length(), replace); pos += replace.length(); } return subject; } 

Si necesita rendimiento, aquí hay una función optimizada que modifica la cadena de entrada, no crea una copia de la cadena:

 void ReplaceStringInPlace(std::string& subject, const std::string& search, const std::string& replace) { size_t pos = 0; while ((pos = subject.find(search, pos)) != std::string::npos) { subject.replace(pos, search.length(), replace); pos += replace.length(); } } 

Pruebas:

 std::string input = "abc abc def"; std::cout << "Input string: " << input << std::endl; std::cout << "ReplaceString() return value: " << ReplaceString(input, "bc", "!!") << std::endl; std::cout << "ReplaceString() input string not modified: " << input << std::endl; ReplaceStringInPlace(input, "bc", "??"); std::cout << "ReplaceStringInPlace() input string modified: " << input << std::endl; 

Salida:

 Input string: abc abc def ReplaceString() return value: a!! a!! def ReplaceString() input string not modified: abc abc def ReplaceStringInPlace() input string modified: a?? a?? def 

Sí: replace_all es uno de los algoritmos de la cadena de impulso:

Aunque no es una biblioteca estándar, tiene algunas cosas en la biblioteca estándar:

  1. Notación más natural basada en rangos en lugar de pares de iteradores. Esto es bueno porque puede anidar manipulaciones de cadenas (por ejemplo, replace_all nested dentro de un trim ). Eso es un poco más complicado para las funciones de biblioteca estándar.
  2. Lo completo. Esto no es difícil de ser “mejor” en; la biblioteca estándar es bastante espartana. Por ejemplo, los algoritmos de cadena de refuerzo le dan un control explícito sobre cómo se realizan las manipulaciones de cadena (es decir, en el lugar oa través de una copia).
 #include  #include  using namespace std; int main () { string str("one three two four"); string str2("three"); str.replace(str.find(str2),str2.length(),"five"); cout << str << endl; return 0; } 

Salida

 one five two four 

como algunos dicen boost :: replace_all

aquí un ejemplo ficticio:

  #include  std::string path("file.gz"); boost::replace_all(path, ".gz", ".zip"); 

No es exactamente eso, pero std::string tiene muchas funciones de replace sobrecargado.

Consulte este enlace para ver la explicación de cada uno, con ejemplos de cómo se usan.

Además, hay varias versiones de funciones string::find (enumeradas a continuación) que puede usar junto con string::replace .

  • encontrar
  • rfind
  • find_first_of
  • find_last_of
  • find_first_not_of
  • find_last_not_of

Además, tenga en cuenta que hay varias versiones de funciones de replace disponibles de que también puede usar (en lugar de string::replace ):

  • reemplazar
  • replace_if
  • replace_copy
  • replace_copy_if
 // replaced text will be in buffer. void Replace(char* buffer, const char* source, const char* oldStr, const char* newStr) { if(buffer==NULL || source == NULL || oldStr == NULL || newStr == NULL) return; int slen = strlen(source); int olen = strlen(oldStr); int nlen = strlen(newStr); if(olen>slen) return; int ix=0; for(int i=0;i 

Aquí está la versión que terminé escribiendo que reemplaza todas las instancias de la cadena objective en una cadena dada. Funciona en cualquier tipo de cadena.

 template  T &replace ( T &str, const U &from, const U &to) { size_t pos; size_t offset = 0; const size_t increment = to.size(); while ((pos = str.find(from, offset)) != T::npos) { str.replace(pos, from.size(), to); offset = pos + increment; } return str; } 

Ejemplo:

 auto foo = "this is a test"s; replace(foo, "is"s, "wis"s); cout << foo; 

Salida:

 thwis wis a test 

Tenga en cuenta que incluso si la cadena de búsqueda aparece en la cadena de reemplazo, esto funciona correctamente.