occurrences from ejemplo and all c++ string text str-replace

from - Cómo eliminar acentos y tilde en un C++ std:: string



std:: string replace all occurrences of char (11)

Tengo un problema con una cadena en C ++ que tiene varias palabras en español. Esto significa que tengo muchas palabras con acentos y tildes. Quiero reemplazarlos por sus homólogos no acentuados. Ejemplo: Quiero reemplazar esta palabra: "había" por habia. Intenté reemplazarlo directamente pero con reemplazar el método de la clase de cadena, pero no pude hacer que funcionara.

Estoy usando este código:

for (it= dictionary.begin(); it != dictionary.end(); it++) { strMine=(it->first); found=toReplace.find_first_of(strMine); while (found!=std::string::npos) { strAux=(it->second); toReplace.erase(found,strMine.length()); toReplace.insert(found,strAux); found=toReplace.find_first_of(strMine,found+1); } }

Donde el dictionary es un mapa como este (con más entradas):

dictionary.insert ( std::pair<std::string,std::string>("á","a") ); dictionary.insert ( std::pair<std::string,std::string>("é","e") ); dictionary.insert ( std::pair<std::string,std::string>("í","i") ); dictionary.insert ( std::pair<std::string,std::string>("ó","o") ); dictionary.insert ( std::pair<std::string,std::string>("ú","u") ); dictionary.insert ( std::pair<std::string,std::string>("ñ","n") );

y toReplace cadenas es:

std::string toReplace="á-é-í-ó-ú-ñ-á-é-í-ó-ú-ñ";

Obviamente debo estar perdiendo algo. No puedo resolverlo. ¿Hay alguna biblioteca que pueda usar?

Gracias,


Es posible que desee consultar la biblioteca de impulso ( http://www.boost.org/ ).

Tiene una biblioteca de expresiones regulares, que puede usar. Además, tiene una biblioteca específica que tiene algunas funciones para la manipulación de cadenas ( enlace ), incluido el reemplazo.


Estaba usando Unix, olvidé mencionarlo, pero corro tr como este

$ tr áéíóú aeiou
á-é-í-ó-ú
ue-uo-uu-uu-uu

no funciona como se espera Creo que tiene que ver con unicode y string class.


En primer lugar, esta es una muy mala idea: estás destruyendo el lenguaje de alguien al eliminar las letras. Aunque los puntos extra en palabras como "ingenuo" parecen superfluos para las personas que solo hablan inglés, hay literalmente miles de sistemas de escritura en el mundo en los que tales distinciones son muy importantes. Escribir software para mutilar el habla de alguien te coloca directamente en el lado equivocado de la tensión entre usar computadoras como medio para ampliar el ámbito de la expresión humana frente a las herramientas de opresión.

¿Cuál es la razón por la que intentas hacer esto? ¿Hay algo más allá en la línea de asfixia en los acentos? A muchas personas les encantaría ayudarte a resolver eso.

Dicho esto, libicu puede hacer esto por ti. Abra la demostración de transformación ; copie y pegue su texto en español en el cuadro "Entrada"; entrar

NFD; [:M:] remove; NFC

como "Compuesto 1" y haga clic en transformar.

(Con la ayuda de la diapositiva 9 de las Transformaciones Unicode en ICU . Las Diapositivas 29-30 muestran cómo usar la API).


Intenta usar std :: wstring en lugar de std :: string. UTF-16 debería funcionar (a diferencia de ASCII).


Lo que pasa es que estoy desarrollando una aplicación con vencimiento en 5 días para la universidad. Es un programa que indexará el texto dentro de la etiqueta en páginas HTML (no puedo usar apache lucene para crear el índice también). Sin embargo, no voy a indexar todas las palabras, debo eliminar todas las palabras vacías, usar la derivación y hacer todo el texto en minúscula. Según lo solicitado por nuestro maestro, debemos eliminar acentos y tilde en las palabras. Espero que esto aclare un poco las cosas.

Saludos,


Si puede (si está ejecutando Unix), le sugiero usar la función tr para esto: está hecho a medida para este propósito. Recuerde, no hay código == no hay código con errores. :-)

Editar: Lo siento, tienes razón, tr no parece funcionar. ¿Qué tal sed ? Es un guión bastante estúpido que he escrito, pero funciona para mí.

#!/bin/sed -f s/á/a/g; s/é/e/g; s/í/i/g; s/ó/o/g; s/ú/u/g; s/ñ/n/g;


Definitivamente creo que deberías investigar la raíz del problema. Es decir, busque una solución que le permita admitir caracteres codificados en Unicode o para la configuración regional del usuario.

Habiendo dicho eso, tu problema es que estás lidiando con cadenas de caracteres múltiples. Hay std::wstring pero no estoy seguro de que use eso. Por un lado, los caracteres anchos no están destinados a manejar codificaciones de ancho variable. Este agujero es profundo, así que lo dejo así.

Ahora, como para el resto de su código, es propenso a errores porque mezcla la lógica de bucle con lógica de traducción. Por lo tanto, al menos dos tipos de errores pueden ocurrir: errores de traducción y bucles. Utiliza STL, puede ayudarte mucho con la parte de bucle.

La siguiente es una solución aproximada para reemplazar caracteres en una cadena.

main.cpp :

#include <iostream> #include <string> #include <iterator> #include <algorithm> #include "translate_characters.h" using namespace std; int main() { string text; cin.unsetf(ios::skipws); transform(istream_iterator<char>(cin), istream_iterator<char>(), inserter(text, text.end()), translate_characters()); cout << text << endl; return 0; }

translate_characters.h :

#ifndef TRANSLATE_CHARACTERS_H #define TRANSLATE_CHARACTERS_H #include <functional> #include <map> class translate_characters : public std::unary_function<const char,char> { public: translate_characters(); char operator()(const char c); private: std::map<char, char> characters_map; }; #endif // TRANSLATE_CHARACTERS_H

translate_characters.cpp :

#include "translate_characters.h" using namespace std; translate_characters::translate_characters() { characters_map.insert(make_pair(''e'', ''a'')); } char translate_characters::operator()(const char c) { map<char, char>::const_iterator translation_pos(characters_map.find(c)); if( translation_pos == characters_map.end() ) return c; return translation_pos->second; }


No pude vincular las bibliotecas de ICU, pero sigo pensando que es la mejor solución. Como necesito que este programa sea funcional lo más pronto posible, hice un pequeño programa (que tengo que mejorar) y lo voy a usar. Gracias a todos por sus sugerencias y respuestas.

Aquí está el código que voy a usar:

for (it= dictionary.begin(); it != dictionary.end(); it++) { strMine=(it->first); found=toReplace.find(strMine); while (found != std::string::npos) { strAux=(it->second); toReplace.erase(found,2); toReplace.insert(found,strAux); found=toReplace.find(strMine,found+1); } }

Lo cambiaré la próxima vez que tenga que activar mi programa para su corrección (en aproximadamente 6 semanas).


No estoy de acuerdo con la respuesta actualmente "aprobada". La pregunta tiene mucho sentido cuando indexas texto. Al igual que la búsqueda insensible a mayúsculas / minúsculas, la búsqueda insensible al acento es una buena idea. "ingenuo" coincide con "Naïve" coincide con "ingenuo" con "NAİVE" ( ¿ sabes que una mayúscula es İ en turco? Es por eso que ignoras los acentos)

Ahora, el mejor algoritmo se insinúa en la respuesta aprobada: use NKD (descomposición) para descomponer las letras acentuadas en la letra de la base y un acento separado, y luego elimine todos los acentos.

Sin embargo, tiene poco sentido la recomposición posterior. Eliminaste la mayoría de las secuencias que cambiarían, y las demás son, para todos los efectos, idénticas de todos modos. ¿Cuál es la diferencia entre æ en NKC y æ en NKD?


Me sorprende que algunas personas digan que no debes desacralizar a los personajes. Tener acentos en los caracteres de los nombres de archivos puede provocar muchos problemas cuando se utilizan programas escritos de manera manifiesta por programadores que no permitieron esto.


Estoy totalmente 100% a favor de usar Unicode y no perder información importante como los acentos, pero a veces es necesario hacer algo como esto. Lo mejor es no adivinar las razones de las personas para querer una función en particular. En mi caso, estoy buscando hacer esto con el fin de buscar textos "similares" (lo que a menudo significa textos escritos, incorrectamente, sin acentos).

Alguien siempre tendrá una razón válida.