Necesito quitar acentos de un string, llevo 2 horas y he probado todo lo que se me ocurre, ya dudo hasta si es posible quitarlos con c++.
¿Se os ocurre algo?
Los acentos los llevan solo las vocales, hay 5 vocales. Las vocales con acento representan 5 carácteres que están fuera del rango ASCII.
printf("%d %d %d %d %d", 'á', 'é', 'í', 'ó', 'ú');
La salida es:
-31 -23 -19 -13 -6
Simplemente cuando encuentre un caracter con uno de esos valores lo tienes que sustituir por el caracter ASCII de la vocal sin acentuación.
if(caracter==-31)
{
caracter='a';
}
Edito: o que leches, simplemente:
if(caracter=='á')
{
caracter='a';
}
Creo haber entendido que quiere quitar los acentos para sustituirlos por vocales sin acentos. Si quieres eliminar los acentos de una cadena, utiliza este método para identificarlos y luego simplemente copia caracter a caracter en otra cadena, utilizando a ser posible reserva de memoria dinámica.
Saludos.
if( cadena == 'á')
no se puede, y ami me sale que las vocales con acento valen dos char
Pero que quieres hacer, ¿eliminar los acentos o cambiar los carácteres por vocales sin acento?
Edito: no puedes igualar una cadena a un caracter.
Tendrías que coger un elemento de la cadena, ejemplo cadena[0].
Saludos.
Prueba esto:
string cadena = "hola quiero eliminar los caráceteres acentuados de ésta cadéna";
remove(cadena.begin(), cadena.end(), 'á');
remove(cadena.begin(), cadena.end(), 'é');
remove(cadena.begin(), cadena.end(), 'í');
remove(cadena.begin(), cadena.end(), 'ó');
remove(cadena.begin(), cadena.end(), 'ù');
printf("%s", cadena.c_str());
Salida:
Citarhola quiero eliminar los carceteres acentuados de sta cadna
:xD :xD :xD :xD
El objetivo el transformar unas 15000 urls, quiero quitar acentos de mayúsculas, minúsculas y la ñ, el problema los acentos no caben en un char y por eso no se puede comparar.
void quitarAcentos(std::string &str){
static const std::string t = "aáàâäeéèêëiíìîïoóòôöuúùûüAÁÀÄEÉÈÊËIÍÌÎÏOÓÒÔÖUÚÙÛÜnññññNÑÑÑÑ";
static const unsigned char n = 5; // Numero de acentos diferentes (+ base) por vocal
for(int i=0; i<str.size(); i++){
size_t pos = t.find(str[i]);
if(pos!=std::string::npos){
str[i] = t[(pos/n)*n];
}
}
}
EDITO: La A mayúscula con acento circulflejo (^) no se ve. Acuerdate de añadirla si usas este código.
Si el objetivo es que solo haya chars ASCII valdría algo como
#include <iostream>
#include <string>
int main()
{
std::string s;
std::cin >> s;
for(unsigned c : s)
if(c < 127)
std::cout << char(c);
}
Cita de: user-marcos en 10 Julio 2015, 00:22 AM
if( cadena == 'á')
no se puede, y ami me sale que las vocales con acento valen dos char
Pasa el error que te lanza, para saber todos los datos.
Cita de: ivancea96 en 10 Julio 2015, 00:38 AM
Pasa el error que te lanza, para saber todos los datos.
Eso es lo mismo que hacer
int n;
if ( n == 5.55)
esta fuera de rango
Cita de: ivancea96 en 10 Julio 2015, 00:32 AM
void quitarAcentos(std::string &str){
static const std::string t = "aáàâäeéèêëiíìîïoóòôöuúùûüAÁÀÄEÉÈÊËIÍÌÎÏOÓÒÔÖUÚÙÛÜnññññNÑÑÑÑ";
static const unsigned char n = 5; // Numero de acentos diferentes (+ base) por vocal
for(int i=0; i<str.size(); i++){
size_t pos = t.find(str[i]);
if(pos!=std::string::npos){
str[i] = t[(pos/n)*n];
}
}
}
EDITO: La A mayúscula con acento circulflejo (^) no se ve. Acuerdate de añadirla si usas este código.
string s = "áéíóú";
quitarAcentos(s);
cout << s;
//salida ->aaa�a�a�a�
Empiezo a pensar que el problema lo tengo en el ordenador, quizá me falte instalar más codificaciones.
El error en la instrucción de antes. El error da más información.
A todo esto, pusiste
cadena == 'á'
¿cadena es un char? ¿No será un char*?
Cita de: user-marcos en 10 Julio 2015, 00:45 AM
Eso es lo mismo que hacer
int n;
if ( n == 5.55)
esta fuera de rango
Te refieres a este warning
Citarwarning: multi-character character constant [-Wmultichar]
? En ese caso no es un error, es un warning, que esta bien tratarlos como errores pero no lo son, aunque no se que mensaje te salio y como lo trato el compilador
¿Qué compilador utilizas? ¿Qué codificación tiene el fichero .cpp?
string s = "á";
if(s == 'á')
cout << "\nok";
el error:
a.cc:14:11: warning: multi-character character constant [-Wmultichar]
if(s == 'á')
^
a.cc: In function 'int main()':
a.cc:14:8: error: no match for 'operator==' (operand types are 'std::string {aka std::basic_string<char>}' and 'int')
if(s == 'á')
^
a.cc:14:8: note: candidates are:
In file included from /usr/include/c++/4.8/iosfwd:40:0,
from /usr/include/c++/4.8/ios:38,
from /usr/include/c++/4.8/ostream:38,
from /usr/include/c++/4.8/iostream:39,
from a.cc:1:
/usr/include/c++/4.8/bits/postypes.h:216:5: note: template<class _StateT> bool std::operator==(const std::fpos<_StateT>&, const std::fpos<_StateT>&)
operator==(const fpos<_StateT>& __lhs, const fpos<_StateT>& __rhs)
^
/usr/include/c++/4.8/bits/postypes.h:216:5: note: template argument deduction/substitution failed:
a.cc:14:11: note: 'std::string {aka std::basic_string<char>}' is not derived from 'const std::fpos<_StateT>'
if(s == 'á')
^
In file included from /usr/include/c++/4.8/bits/stl_algobase.h:64:0,
from /usr/include/c++/4.8/bits/char_traits.h:39,
from /usr/include/c++/4.8/ios:40,
from /usr/include/c++/4.8/ostream:38,
from /usr/include/c++/4.8/iostream:39,
from a.cc:1:
/usr/include/c++/4.8/bits/stl_pair.h:214:5: note: template<class _T1, class _T2> bool std::operator==(const std::pair<_T1, _T2>&, const std::pair<_T1, _T2>&)
operator==(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y)
^
/usr/include/c++/4.8/bits/stl_pair.h:214:5: note: template argument deduction/substitution failed:
a.cc:14:11: note: 'std::string {aka std::basic_string<char>}' is not derived from 'const std::pair<_T1, _T2>'
if(s == 'á')
^
In file included from /usr/include/c++/4.8/bits/stl_algobase.h:67:0,
from /usr/include/c++/4.8/bits/char_traits.h:39,
from /usr/include/c++/4.8/ios:40,
from /usr/include/c++/4.8/ostream:38,
from /usr/include/c++/4.8/iostream:39,
from a.cc:1:
/usr/include/c++/4.8/bits/stl_iterator.h:291:5: note: template<class _Iterator> bool std::operator==(const std::reverse_iterator<_Iterator>&, const std::reverse_iterator<_Iterator>&)
operator==(const reverse_iterator<_Iterator>& __x,
^
/usr/include/c++/4.8/bits/stl_iterator.h:291:5: note: template argument deduction/substitution failed:
a.cc:14:11: note: 'std::string {aka std::basic_string<char>}' is not derived from 'const std::reverse_iterator<_Iterator>'
if(s == 'á')
^
In file included from /usr/include/c++/4.8/bits/stl_algobase.h:67:0,
from /usr/include/c++/4.8/bits/char_traits.h:39,
from /usr/include/c++/4.8/ios:40,
from /usr/include/c++/4.8/ostream:38,
from /usr/include/c++/4.8/iostream:39,
from a.cc:1:
/usr/include/c++/4.8/bits/stl_iterator.h:341:5: note: template<class _IteratorL, class _IteratorR> bool std::operator==(const std::reverse_iterator<_Iterator>&, const std::reverse_iterator<_IteratorR>&)
operator==(const reverse_iterator<_IteratorL>& __x,
^
/usr/include/c++/4.8/bits/stl_iterator.h:341:5: note: template argument deduction/substitution failed:
a.cc:14:11: note: 'std::string {aka std::basic_string<char>}' is not derived from 'const std::reverse_iterator<_Iterator>'
if(s == 'á')
^
In file included from /usr/include/c++/4.8/string:41:0,
from /usr/include/c++/4.8/bits/locale_classes.h:40,
from /usr/include/c++/4.8/bits/ios_base.h:41,
from /usr/include/c++/4.8/ios:42,
from /usr/include/c++/4.8/ostream:38,
from /usr/include/c++/4.8/iostream:39,
from a.cc:1:
/usr/include/c++/4.8/bits/allocator.h:128:5: note: template<class _T1, class _T2> bool std::operator==(const std::allocator<_CharT>&, const std::allocator<_T2>&)
operator==(const allocator<_T1>&, const allocator<_T2>&)
^
/usr/include/c++/4.8/bits/allocator.h:128:5: note: template argument deduction/substitution failed:
a.cc:14:11: note: 'std::string {aka std::basic_string<char>}' is not derived from 'const std::allocator<_CharT>'
if(s == 'á')
^
In file included from /usr/include/c++/4.8/string:41:0,
from /usr/include/c++/4.8/bits/locale_classes.h:40,
from /usr/include/c++/4.8/bits/ios_base.h:41,
from /usr/include/c++/4.8/ios:42,
from /usr/include/c++/4.8/ostream:38,
from /usr/include/c++/4.8/iostream:39,
from a.cc:1:
/usr/include/c++/4.8/bits/allocator.h:133:5: note: template<class _Tp> bool std::operator==(const std::allocator<_CharT>&, const std::allocator<_CharT>&)
operator==(const allocator<_Tp>&, const allocator<_Tp>&)
^
/usr/include/c++/4.8/bits/allocator.h:133:5: note: template argument deduction/substitution failed:
a.cc:14:11: note: 'std::string {aka std::basic_string<char>}' is not derived from 'const std::allocator<_CharT>'
if(s == 'á')
^
In file included from /usr/include/c++/4.8/string:52:0,
from /usr/include/c++/4.8/bits/locale_classes.h:40,
from /usr/include/c++/4.8/bits/ios_base.h:41,
from /usr/include/c++/4.8/ios:42,
from /usr/include/c++/4.8/ostream:38,
from /usr/include/c++/4.8/iostream:39,
from a.cc:1:
/usr/include/c++/4.8/bits/basic_string.h:2486:5: note: template<class _CharT, class _Traits, class _Alloc> bool std::operator==(const std::basic_string<_CharT, _Traits, _Alloc>&, const std::basic_string<_CharT, _Traits, _Alloc>&)
operator==(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
^
/usr/include/c++/4.8/bits/basic_string.h:2486:5: note: template argument deduction/substitution failed:
a.cc:14:11: note: mismatched types 'const std::basic_string<_CharT, _Traits, _Alloc>' and 'int'
if(s == 'á')
^
In file included from /usr/include/c++/4.8/string:52:0,
from /usr/include/c++/4.8/bits/locale_classes.h:40,
from /usr/include/c++/4.8/bits/ios_base.h:41,
from /usr/include/c++/4.8/ios:42,
from /usr/include/c++/4.8/ostream:38,
from /usr/include/c++/4.8/iostream:39,
from a.cc:1:
/usr/include/c++/4.8/bits/basic_string.h:2493:5: note: template<class _CharT> typename __gnu_cxx::__enable_if<std::__is_char<_Tp>::__value, bool>::__type std::operator==(const std::basic_string<_CharT>&, const std::basic_string<_CharT>&)
operator==(const basic_string<_CharT>& __lhs,
^
/usr/include/c++/4.8/bits/basic_string.h:2493:5: note: template argument deduction/substitution failed:
a.cc:14:11: note: mismatched types 'const std::basic_string<_CharT>' and 'int'
if(s == 'á')
^
In file included from /usr/include/c++/4.8/string:52:0,
from /usr/include/c++/4.8/bits/locale_classes.h:40,
from /usr/include/c++/4.8/bits/ios_base.h:41,
from /usr/include/c++/4.8/ios:42,
from /usr/include/c++/4.8/ostream:38,
from /usr/include/c++/4.8/iostream:39,
from a.cc:1:
/usr/include/c++/4.8/bits/basic_string.h:2507:5: note: template<class _CharT, class _Traits, class _Alloc> bool std::operator==(const _CharT*, const std::basic_string<_CharT, _Traits, _Alloc>&)
operator==(const _CharT* __lhs,
^
/usr/include/c++/4.8/bits/basic_string.h:2507:5: note: template argument deduction/substitution failed:
a.cc:14:11: note: mismatched types 'const _CharT*' and 'std::basic_string<char>'
if(s == 'á')
^
In file included from /usr/include/c++/4.8/string:52:0,
from /usr/include/c++/4.8/bits/locale_classes.h:40,
from /usr/include/c++/4.8/bits/ios_base.h:41,
from /usr/include/c++/4.8/ios:42,
from /usr/include/c++/4.8/ostream:38,
from /usr/include/c++/4.8/iostream:39,
from a.cc:1:
/usr/include/c++/4.8/bits/basic_string.h:2519:5: note: template<class _CharT, class _Traits, class _Alloc> bool std::operator==(const std::basic_string<_CharT, _Traits, _Alloc>&, const _CharT*)
operator==(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
^
/usr/include/c++/4.8/bits/basic_string.h:2519:5: note: template argument deduction/substitution failed:
a.cc:14:11: note: mismatched types 'const _CharT*' and 'int'
if(s == 'á')
^
In file included from /usr/include/c++/4.8/bits/locale_facets.h:48:0,
from /usr/include/c++/4.8/bits/basic_ios.h:37,
from /usr/include/c++/4.8/ios:44,
from /usr/include/c++/4.8/ostream:38,
from /usr/include/c++/4.8/iostream:39,
from a.cc:1:
/usr/include/c++/4.8/bits/streambuf_iterator.h:204:5: note: template<class _CharT, class _Traits> bool std::operator==(const std::istreambuf_iterator<_CharT, _Traits>&, const std::istreambuf_iterator<_CharT, _Traits>&)
operator==(const istreambuf_iterator<_CharT, _Traits>& __a,
^
/usr/include/c++/4.8/bits/streambuf_iterator.h:204:5: note: template argument deduction/substitution failed:
a.cc:14:11: note: 'std::string {aka std::basic_string<char>}' is not derived from 'const std::istreambuf_iterator<_CharT, _Traits>'
if(s == 'á')
^
In file included from /usr/include/x86_64-linux-gnu/c++/4.8/bits/c++allocator.h:33:0,
from /usr/include/c++/4.8/bits/allocator.h:46,
from /usr/include/c++/4.8/string:41,
from /usr/include/c++/4.8/bits/locale_classes.h:40,
from /usr/include/c++/4.8/bits/ios_base.h:41,
from /usr/include/c++/4.8/ios:42,
from /usr/include/c++/4.8/ostream:38,
from /usr/include/c++/4.8/iostream:39,
from a.cc:1:
/usr/include/c++/4.8/ext/new_allocator.h:139:5: note: template<class _Tp> bool __gnu_cxx::operator==(const __gnu_cxx::new_allocator<_Tp>&, const __gnu_cxx::new_allocator<_Tp>&)
operator==(const new_allocator<_Tp>&, const new_allocator<_Tp>&)
^
/usr/include/c++/4.8/ext/new_allocator.h:139:5: note: template argument deduction/substitution failed:
a.cc:14:11: note: 'std::string {aka std::basic_string<char>}' is not derived from 'const __gnu_cxx::new_allocator<_Tp>'
if(s == 'á')
^
In file included from /usr/include/c++/4.8/bits/stl_algobase.h:67:0,
from /usr/include/c++/4.8/bits/char_traits.h:39,
from /usr/include/c++/4.8/ios:40,
from /usr/include/c++/4.8/ostream:38,
from /usr/include/c++/4.8/iostream:39,
from a.cc:1:
/usr/include/c++/4.8/bits/stl_iterator.h:811:5: note: template<class _Iterator, class _Container> bool __gnu_cxx::operator==(const __gnu_cxx::__normal_iterator<_Iterator, _Container>&, const __gnu_cxx::__normal_iterator<_Iterator, _Container>&)
operator==(const __normal_iterator<_Iterator, _Container>& __lhs,
^
/usr/include/c++/4.8/bits/stl_iterator.h:811:5: note: template argument deduction/substitution failed:
a.cc:14:11: note: 'std::string {aka std::basic_string<char>}' is not derived from 'const __gnu_cxx::__normal_iterator<_Iterator, _Container>'
if(s == 'á')
^
In file included from /usr/include/c++/4.8/bits/stl_algobase.h:67:0,
from /usr/include/c++/4.8/bits/char_traits.h:39,
from /usr/include/c++/4.8/ios:40,
from /usr/include/c++/4.8/ostream:38,
from /usr/include/c++/4.8/iostream:39,
from a.cc:1:
/usr/include/c++/4.8/bits/stl_iterator.h:805:5: note: template<class _IteratorL, class _IteratorR, class _Container> bool __gnu_cxx::operator==(const __gnu_cxx::__normal_iterator<_IteratorL, _Container>&, const __gnu_cxx::__normal_iterator<_IteratorR, _Container>&)
operator==(const __normal_iterator<_IteratorL, _Container>& __lhs,
^
/usr/include/c++/4.8/bits/stl_iterator.h:805:5: note: template argument deduction/substitution failed:
a.cc:14:11: note: 'std::string {aka std::basic_string<char>}' is not derived from 'const __gnu_cxx::__normal_iterator<_IteratorL, _Container>'
if(s == 'á')
(operand types are 'std::string {aka std::basic_string<char>}' and 'int')
Estás comparando una string con un caracter. No puedes hacer eso. O haces s[0], o haces "á".
Tengo una posible solución PROVISIONAL aunque puede desbordar:
#include<iostream>
#include <cstring>
using namespace std;
bool cod_aux(string &s);
void cod(string &s);
int main()
{
string j = "áóÁsÚíu";
cod(j);
cout << endl << j;//-> aoAsUiu
}
void cod(string &s)
{
string aux = "";
string aux2 = "";
bool add = false;
char auxc;
for(int i = 0; i < s.length(); i++)
{
aux +=s[i];
aux +=s[i+1];
if(cod_aux(aux) == false)
{
aux2 += aux;
i = i +1;
}
else aux2 +=s[i];
aux = "";
}
s = aux2;
}
bool cod_aux(string &s)
{
string aux = s;
if(s == "á")
s = "a";
if(s == "Á")
s = "A";
if(s == "é")
s = "e";
if(s == "É")
s = "E";
if(s == "í")
s = "i";
if(s == "Í")
s = "I";
if(s == "Ó")
s = "O";
if(s == "ó")
s = "o";
if(s == "Ú")
s = "U";
if(s == "ú")
s = "u";
return aux == s;
}
aux +=s[i+1];
Eso puede acceder a s[ s.length() ].
En cualquier caso, string::find() será más interesante que usar tal cadena de if().
Además, trata de hacer comparaciones y asignaciones con caracteres y no con strings. Tal vez simplemente tengas una extraña codificación.
Cita de: ivancea96 en 10 Julio 2015, 01:33 AM
Además, trata de hacer comparaciones y asignaciones con caracteres y no con strings. Tal vez simplemente tengas una extraña codificación.
Si no recuerdo mal á é y demás se almacenan internamente como const char* así que ya esta bien comparar con strings creo.
Cita de: user-marcos en 10 Julio 2015, 00:22 AM
if( cadena == 'á')
no se puede, y ami me sale que las vocales con acento valen dos char
Los caracteres acentuados se componen de dos bytes, mientras los sin acento se representan con un solo byte, intenta probando esto
if( cadena == (unsigned char)('á'))
Saludos
Cita de: Stakewinner00 en 10 Julio 2015, 01:44 AM
Si no recuerdo mal á é y demás se almacenan internamente como const char* así que ya esta bien comparar con strings creo.
Si pero bueno, es preferible comparar con char que es más eficiente xD
De todas formas, user_marcos, prueba con wstring, que utiliza wide char.
Cita de: Coper en 10 Julio 2015, 01:46 AM
Los caracteres acentuados se componen de dos bytes, mientras los sin acento se representan con un solo byte, intenta probando esto
if( cadena == (unsigned char)('á'))
Pero comparar una cosa de la clase std::string con un unsigned char no se puede hacer así tal cual,
Si el código está hecho en utf8 o en latín iso y usas otra codificación en la entrada de texto del terminal no realizará las validaciones ya que á en utf8 no es lo mismo que á en latín iso o en otras codificaciones ya que el valor decimal es diferente.
Lo que yo haría es crear la misma lista blanca pero con sus valores respectivos en decimal y detectar la codificación del texto y en base a eso realizar la conversión
Ahora, una pregunta: necesitas reemplazar únicamente acentos? que pasa con las eñes y ¨? y los demás caracteres especiales que se usan en otros lenguajes?
Mira, acá hay un proyecto que ya hace lo que necesitas:
http://stackoverflow.com/questions/2992066/code-to-strip-diacritical-marks-using-icu
http://stackoverflow.com/questions/144761/how-to-remove-accents-and-tilde-in-a-c-stdstring
http://site.icu-project.org/
Cita de: WHK en 10 Julio 2015, 01:56 AM
Ahora, una pregunta: necesitas reemplazar únicamente acentos? que pasa con las eñes y ¨? y los demás caracteres especiales que se usan en otros lenguajes?
Los demás caracteres los voy a quitar, sólo me insertaban los acentos para que las urls no me pierdan el sentido.
Gracias a todos por la ayuda.
Ahhh es para formatear urls amigables, entonces dale un vistazo a esto:
https://github.com/WordPress/WordPress/blob/master/wp-includes/formatting.php#LC968
Te servirá para crear reglas similares en c++, está hecho en php y es la función nativa de Wordpress para crear las urls amigables:
function remove_accents( $string ) {
if ( !preg_match('/[\x80-\xff]/', $string) )
return $string;
if (seems_utf8($string)) {
$chars = array(
// Decompositions for Latin-1 Supplement
chr(194).chr(170) => 'a', chr(194).chr(186) => 'o',
chr(195).chr(128) => 'A', chr(195).chr(129) => 'A',
chr(195).chr(130) => 'A', chr(195).chr(131) => 'A',
chr(195).chr(132) => 'A', chr(195).chr(133) => 'A',
chr(195).chr(134) => 'AE',chr(195).chr(135) => 'C',
chr(195).chr(136) => 'E', chr(195).chr(137) => 'E',
chr(195).chr(138) => 'E', chr(195).chr(139) => 'E',
chr(195).chr(140) => 'I', chr(195).chr(141) => 'I',
chr(195).chr(142) => 'I', chr(195).chr(143) => 'I',
chr(195).chr(144) => 'D', chr(195).chr(145) => 'N',
chr(195).chr(146) => 'O', chr(195).chr(147) => 'O',
chr(195).chr(148) => 'O', chr(195).chr(149) => 'O',
chr(195).chr(150) => 'O', chr(195).chr(153) => 'U',
chr(195).chr(154) => 'U', chr(195).chr(155) => 'U',
chr(195).chr(156) => 'U', chr(195).chr(157) => 'Y',
chr(195).chr(158) => 'TH',chr(195).chr(159) => 's',
chr(195).chr(160) => 'a', chr(195).chr(161) => 'a',
chr(195).chr(162) => 'a', chr(195).chr(163) => 'a',
chr(195).chr(164) => 'a', chr(195).chr(165) => 'a',
chr(195).chr(166) => 'ae',chr(195).chr(167) => 'c',
chr(195).chr(168) => 'e', chr(195).chr(169) => 'e',
chr(195).chr(170) => 'e', chr(195).chr(171) => 'e',
chr(195).chr(172) => 'i', chr(195).chr(173) => 'i',
chr(195).chr(174) => 'i', chr(195).chr(175) => 'i',
chr(195).chr(176) => 'd', chr(195).chr(177) => 'n',
chr(195).chr(178) => 'o', chr(195).chr(179) => 'o',
chr(195).chr(180) => 'o', chr(195).chr(181) => 'o',
chr(195).chr(182) => 'o', chr(195).chr(184) => 'o',
chr(195).chr(185) => 'u', chr(195).chr(186) => 'u',
chr(195).chr(187) => 'u', chr(195).chr(188) => 'u',
chr(195).chr(189) => 'y', chr(195).chr(190) => 'th',
chr(195).chr(191) => 'y', chr(195).chr(152) => 'O',
// Decompositions for Latin Extended-A
chr(196).chr(128) => 'A', chr(196).chr(129) => 'a',
chr(196).chr(130) => 'A', chr(196).chr(131) => 'a',
chr(196).chr(132) => 'A', chr(196).chr(133) => 'a',
chr(196).chr(134) => 'C', chr(196).chr(135) => 'c',
chr(196).chr(136) => 'C', chr(196).chr(137) => 'c',
chr(196).chr(138) => 'C', chr(196).chr(139) => 'c',
chr(196).chr(140) => 'C', chr(196).chr(141) => 'c',
chr(196).chr(142) => 'D', chr(196).chr(143) => 'd',
chr(196).chr(144) => 'D', chr(196).chr(145) => 'd',
chr(196).chr(146) => 'E', chr(196).chr(147) => 'e',
chr(196).chr(148) => 'E', chr(196).chr(149) => 'e',
chr(196).chr(150) => 'E', chr(196).chr(151) => 'e',
chr(196).chr(152) => 'E', chr(196).chr(153) => 'e',
chr(196).chr(154) => 'E', chr(196).chr(155) => 'e',
chr(196).chr(156) => 'G', chr(196).chr(157) => 'g',
chr(196).chr(158) => 'G', chr(196).chr(159) => 'g',
chr(196).chr(160) => 'G', chr(196).chr(161) => 'g',
chr(196).chr(162) => 'G', chr(196).chr(163) => 'g',
chr(196).chr(164) => 'H', chr(196).chr(165) => 'h',
chr(196).chr(166) => 'H', chr(196).chr(167) => 'h',
chr(196).chr(168) => 'I', chr(196).chr(169) => 'i',
chr(196).chr(170) => 'I', chr(196).chr(171) => 'i',
chr(196).chr(172) => 'I', chr(196).chr(173) => 'i',
chr(196).chr(174) => 'I', chr(196).chr(175) => 'i',
chr(196).chr(176) => 'I', chr(196).chr(177) => 'i',
chr(196).chr(178) => 'IJ',chr(196).chr(179) => 'ij',
chr(196).chr(180) => 'J', chr(196).chr(181) => 'j',
chr(196).chr(182) => 'K', chr(196).chr(183) => 'k',
chr(196).chr(184) => 'k', chr(196).chr(185) => 'L',
chr(196).chr(186) => 'l', chr(196).chr(187) => 'L',
chr(196).chr(188) => 'l', chr(196).chr(189) => 'L',
chr(196).chr(190) => 'l', chr(196).chr(191) => 'L',
chr(197).chr(128) => 'l', chr(197).chr(129) => 'L',
chr(197).chr(130) => 'l', chr(197).chr(131) => 'N',
chr(197).chr(132) => 'n', chr(197).chr(133) => 'N',
chr(197).chr(134) => 'n', chr(197).chr(135) => 'N',
chr(197).chr(136) => 'n', chr(197).chr(137) => 'N',
chr(197).chr(138) => 'n', chr(197).chr(139) => 'N',
chr(197).chr(140) => 'O', chr(197).chr(141) => 'o',
chr(197).chr(142) => 'O', chr(197).chr(143) => 'o',
chr(197).chr(144) => 'O', chr(197).chr(145) => 'o',
chr(197).chr(146) => 'OE',chr(197).chr(147) => 'oe',
chr(197).chr(148) => 'R',chr(197).chr(149) => 'r',
chr(197).chr(150) => 'R',chr(197).chr(151) => 'r',
chr(197).chr(152) => 'R',chr(197).chr(153) => 'r',
chr(197).chr(154) => 'S',chr(197).chr(155) => 's',
chr(197).chr(156) => 'S',chr(197).chr(157) => 's',
chr(197).chr(158) => 'S',chr(197).chr(159) => 's',
chr(197).chr(160) => 'S', chr(197).chr(161) => 's',
chr(197).chr(162) => 'T', chr(197).chr(163) => 't',
chr(197).chr(164) => 'T', chr(197).chr(165) => 't',
chr(197).chr(166) => 'T', chr(197).chr(167) => 't',
chr(197).chr(168) => 'U', chr(197).chr(169) => 'u',
chr(197).chr(170) => 'U', chr(197).chr(171) => 'u',
chr(197).chr(172) => 'U', chr(197).chr(173) => 'u',
chr(197).chr(174) => 'U', chr(197).chr(175) => 'u',
chr(197).chr(176) => 'U', chr(197).chr(177) => 'u',
chr(197).chr(178) => 'U', chr(197).chr(179) => 'u',
chr(197).chr(180) => 'W', chr(197).chr(181) => 'w',
chr(197).chr(182) => 'Y', chr(197).chr(183) => 'y',
chr(197).chr(184) => 'Y', chr(197).chr(185) => 'Z',
chr(197).chr(186) => 'z', chr(197).chr(187) => 'Z',
chr(197).chr(188) => 'z', chr(197).chr(189) => 'Z',
chr(197).chr(190) => 'z', chr(197).chr(191) => 's',
// Decompositions for Latin Extended-B
chr(200).chr(152) => 'S', chr(200).chr(153) => 's',
chr(200).chr(154) => 'T', chr(200).chr(155) => 't',
// Euro Sign
chr(226).chr(130).chr(172) => 'E',
// GBP (Pound) Sign
chr(194).chr(163) => '',
// Vowels with diacritic (Vietnamese)
// unmarked
chr(198).chr(160) => 'O', chr(198).chr(161) => 'o',
chr(198).chr(175) => 'U', chr(198).chr(176) => 'u',
// grave accent
chr(225).chr(186).chr(166) => 'A', chr(225).chr(186).chr(167) => 'a',
chr(225).chr(186).chr(176) => 'A', chr(225).chr(186).chr(177) => 'a',
chr(225).chr(187).chr(128) => 'E', chr(225).chr(187).chr(129) => 'e',
chr(225).chr(187).chr(146) => 'O', chr(225).chr(187).chr(147) => 'o',
chr(225).chr(187).chr(156) => 'O', chr(225).chr(187).chr(157) => 'o',
chr(225).chr(187).chr(170) => 'U', chr(225).chr(187).chr(171) => 'u',
chr(225).chr(187).chr(178) => 'Y', chr(225).chr(187).chr(179) => 'y',
// hook
chr(225).chr(186).chr(162) => 'A', chr(225).chr(186).chr(163) => 'a',
chr(225).chr(186).chr(168) => 'A', chr(225).chr(186).chr(169) => 'a',
chr(225).chr(186).chr(178) => 'A', chr(225).chr(186).chr(179) => 'a',
chr(225).chr(186).chr(186) => 'E', chr(225).chr(186).chr(187) => 'e',
chr(225).chr(187).chr(130) => 'E', chr(225).chr(187).chr(131) => 'e',
chr(225).chr(187).chr(136) => 'I', chr(225).chr(187).chr(137) => 'i',
chr(225).chr(187).chr(142) => 'O', chr(225).chr(187).chr(143) => 'o',
chr(225).chr(187).chr(148) => 'O', chr(225).chr(187).chr(149) => 'o',
chr(225).chr(187).chr(158) => 'O', chr(225).chr(187).chr(159) => 'o',
chr(225).chr(187).chr(166) => 'U', chr(225).chr(187).chr(167) => 'u',
chr(225).chr(187).chr(172) => 'U', chr(225).chr(187).chr(173) => 'u',
chr(225).chr(187).chr(182) => 'Y', chr(225).chr(187).chr(183) => 'y',
// tilde
chr(225).chr(186).chr(170) => 'A', chr(225).chr(186).chr(171) => 'a',
chr(225).chr(186).chr(180) => 'A', chr(225).chr(186).chr(181) => 'a',
chr(225).chr(186).chr(188) => 'E', chr(225).chr(186).chr(189) => 'e',
chr(225).chr(187).chr(132) => 'E', chr(225).chr(187).chr(133) => 'e',
chr(225).chr(187).chr(150) => 'O', chr(225).chr(187).chr(151) => 'o',
chr(225).chr(187).chr(160) => 'O', chr(225).chr(187).chr(161) => 'o',
chr(225).chr(187).chr(174) => 'U', chr(225).chr(187).chr(175) => 'u',
chr(225).chr(187).chr(184) => 'Y', chr(225).chr(187).chr(185) => 'y',
// acute accent
chr(225).chr(186).chr(164) => 'A', chr(225).chr(186).chr(165) => 'a',
chr(225).chr(186).chr(174) => 'A', chr(225).chr(186).chr(175) => 'a',
chr(225).chr(186).chr(190) => 'E', chr(225).chr(186).chr(191) => 'e',
chr(225).chr(187).chr(144) => 'O', chr(225).chr(187).chr(145) => 'o',
chr(225).chr(187).chr(154) => 'O', chr(225).chr(187).chr(155) => 'o',
chr(225).chr(187).chr(168) => 'U', chr(225).chr(187).chr(169) => 'u',
// dot below
chr(225).chr(186).chr(160) => 'A', chr(225).chr(186).chr(161) => 'a',
chr(225).chr(186).chr(172) => 'A', chr(225).chr(186).chr(173) => 'a',
chr(225).chr(186).chr(182) => 'A', chr(225).chr(186).chr(183) => 'a',
chr(225).chr(186).chr(184) => 'E', chr(225).chr(186).chr(185) => 'e',
chr(225).chr(187).chr(134) => 'E', chr(225).chr(187).chr(135) => 'e',
chr(225).chr(187).chr(138) => 'I', chr(225).chr(187).chr(139) => 'i',
chr(225).chr(187).chr(140) => 'O', chr(225).chr(187).chr(141) => 'o',
chr(225).chr(187).chr(152) => 'O', chr(225).chr(187).chr(153) => 'o',
chr(225).chr(187).chr(162) => 'O', chr(225).chr(187).chr(163) => 'o',
chr(225).chr(187).chr(164) => 'U', chr(225).chr(187).chr(165) => 'u',
chr(225).chr(187).chr(176) => 'U', chr(225).chr(187).chr(177) => 'u',
chr(225).chr(187).chr(180) => 'Y', chr(225).chr(187).chr(181) => 'y',
// Vowels with diacritic (Chinese, Hanyu Pinyin)
chr(201).chr(145) => 'a',
// macron
chr(199).chr(149) => 'U', chr(199).chr(150) => 'u',
// acute accent
chr(199).chr(151) => 'U', chr(199).chr(152) => 'u',
// caron
chr(199).chr(141) => 'A', chr(199).chr(142) => 'a',
chr(199).chr(143) => 'I', chr(199).chr(144) => 'i',
chr(199).chr(145) => 'O', chr(199).chr(146) => 'o',
chr(199).chr(147) => 'U', chr(199).chr(148) => 'u',
chr(199).chr(153) => 'U', chr(199).chr(154) => 'u',
// grave accent
chr(199).chr(155) => 'U', chr(199).chr(156) => 'u',
);
// Used for locale-specific rules
$locale = get_locale();
if ( 'de_DE' == $locale || 'de_DE_formal' == $locale ) {
$chars[ chr(195).chr(132) ] = 'Ae';
$chars[ chr(195).chr(164) ] = 'ae';
$chars[ chr(195).chr(150) ] = 'Oe';
$chars[ chr(195).chr(182) ] = 'oe';
$chars[ chr(195).chr(156) ] = 'Ue';
$chars[ chr(195).chr(188) ] = 'ue';
$chars[ chr(195).chr(159) ] = 'ss';
} elseif ( 'da_DK' === $locale ) {
$chars[ chr(195).chr(134) ] = 'Ae';
$chars[ chr(195).chr(166) ] = 'ae';
$chars[ chr(195).chr(152) ] = 'Oe';
$chars[ chr(195).chr(184) ] = 'oe';
$chars[ chr(195).chr(133) ] = 'Aa';
$chars[ chr(195).chr(165) ] = 'aa';
}
$string = strtr($string, $chars);
} else {
$chars = array();
// Assume ISO-8859-1 if not UTF-8
$chars['in'] = chr(128).chr(131).chr(138).chr(142).chr(154).chr(158)
.chr(159).chr(162).chr(165).chr(181).chr(192).chr(193).chr(194)
.chr(195).chr(196).chr(197).chr(199).chr(200).chr(201).chr(202)
.chr(203).chr(204).chr(205).chr(206).chr(207).chr(209).chr(210)
.chr(211).chr(212).chr(213).chr(214).chr(216).chr(217).chr(218)
.chr(219).chr(220).chr(221).chr(224).chr(225).chr(226).chr(227)
.chr(228).chr(229).chr(231).chr(232).chr(233).chr(234).chr(235)
.chr(236).chr(237).chr(238).chr(239).chr(241).chr(242).chr(243)
.chr(244).chr(245).chr(246).chr(248).chr(249).chr(250).chr(251)
.chr(252).chr(253).chr(255);
$chars['out'] = "EfSZszYcYuAAAAAACEEEEIIIINOOOOOOUUUUYaaaaaaceeeeiiiinoooooouuuuyy";
$string = strtr($string, $chars['in'], $chars['out']);
$double_chars = array();
$double_chars['in'] = array(chr(140), chr(156), chr(198), chr(208), chr(222), chr(223), chr(230), chr(240), chr(254));
$double_chars['out'] = array('OE', 'oe', 'AE', 'DH', 'TH', 'ss', 'ae', 'dh', 'th');
$string = str_replace($double_chars['in'], $double_chars['out'], $string);
}
return $string;
}