/**
  * Implémentation Qt/C++ pour le projet AbulÉdu
  * 2012 - Éric Seigne <eric.seigne@ryxeo.com>
  * Licence GNU/GPL v3 après accord explicite de l'auteur initial pour placer l'implémentation C++
  * de son algorithme sous cette licence, Plus d'informations ci-dessous.
  *
  * Url source: http://www.roudoudou.com/phonetic.php
  *
  * Source: SOUNDEX FR
  * Édouard BERGÉ © 12.2007 v1.2
  *  ---------------------------------------------------------------------------------------------------------
  *  Cet algorithme et son application en PHP sont tous deux distribués sous la licence
  *  Creative Commons Paternité - Pas d'Utilisation Commerciale 2.0
  *  http://creativecommons.org/licenses/by-nc/2.0/fr/
  *  Vous êtes libres :
  *  - de reproduire, distribuer et communiquer cette création au public
  *  - de modifier cette création
  *  Selon les conditions suivantes :
  *  - Paternité. Vous devez citer le nom de l'auteur original de la manière indiquée
  *  par l'auteur de l'oeuvre ou le titulaire des droits qui vous confère cette
  *  autorisation (mais pas d'une manière qui suggérerait qu'ils vous soutiennent
  *  ou approuvent votre utilisation de l'oeuvre).
  *  Demande de l'auteur: Citer "Édouard BERGÉ" et/ou " http://www.roudoudou.com"
  *  - Pas d'Utilisation Commerciale. Vous n'avez pas le droit d'utiliser cette
  *  création à des fins commerciales sauf autorisation de l'auteur.
  *  ---------------------------------------------------------------------------------------------------------
  *
  */
QString phonetique(QString in)
{
    QString out(in);
    QString sauvePourMotsTresCourts;
    QString sauvePourMotsTresCourtsBis;

    QStringList min2maj;
    min2maj << "é" << "É" << "è" << "È" << "ë" << "Ë" << "ê" << "Ê" << "á" << "Á" << "â" << "Â" << "à" << "À" << "Ä" << "A"
            << "Â" << "A" << "å" << "Å" << "ã" << "Ã" << "æ" << "Æ" << "ï" << "Ï" << "î" << "Î" << "ì" << "Ì" << "í" << "Í"
            << "ô" << "Ô" << "ö" << "Ö" << "ò" << "Ò" << "ó" << "Ó" << "õ" << "Õ" << "ø" << "Ø" << "œ" << "Œ"
            << "ú" << "Ú" << "ù" << "Ù" << "û" << "Û" << "ü" << "Ü" << "ç" << "Ç" << "ñ" << "Ñ" << "ß" << "S";
    QStringList accents;
    accents << "É" << "E" << "È" << "E" << "Ë" << "E" << "Ê" << "E" << "Á" << "A" << "À" << "A" << "Ä" << "A" << "Â" << "A"
            << "Å" << "A" << "Ã" << "A" << "Æ" << "E" << "Ï" << "I" << "Î" << "I" << "Ì" << "I" << "Í" << "I"
            << "Ô" << "O" << "Ö" << "O" << "Ò" << "O" << "Ó" << "O" << "Õ" << "O" << "Ø" << "O" << "Œ" << "OEU"
            << "Ú" << "U" << "Ù" << "U" << "Û" << "U" << "Ü" << "U" << "Ñ" << "N" << "Ç" << "S" << "¿" << "E";

    // minuscules accentuées ou composées en majuscules simples
    for(int i = 0; i < min2maj.size()-1; i+=2) {
        out.replace(min2maj.at(i),min2maj.at(i+1));
    }

    // majuscules accentuées ou composées en majuscules simples
    for(int i = 0; i < accents.size()-1; i+=2) {
        out.replace(accents.at(i),accents.at(i+1));
    }

    //tout en majuscule
    out = out.toUpper();

    // on garde uniquement les lettres de A à Z
    out.remove(QRegExp("[^A-Z]"));

    // on sauve le code (utilisé pour les mots très courts)
    sauvePourMotsTresCourts = out;

    // pré traitement OO... -> OU
    out.replace(QRegExp("O[O]+"),"OU");

    // pré traitement SAOU -> SOU
    out.replace(QRegExp("SAOU"),"SOU");

    // pré traitement OES -> OS
    out.replace(QRegExp("OES"),"OS");

    // pré traitement CCH -> K
    out.replace(QRegExp("CCH"),"K");

    // CCI CCY CCE
    out.replace(QRegExp("CC([IYE])"),"KS\\1");

    // supression des répétitions
    out.replace(QRegExp("(.)\\1"),"\\1");

    // quelques cas particuliers
    if (out=="CD") return(out);
    if (out=="BD") return(out);
    if (out=="BV") return(out);
    if (out=="TABAC") return("TABA");
    if (out=="FEU") return("FE");
    if (out=="FE") return(out);
    if (out=="FER") return(out);
    if (out=="FIEF") return(out);
    if (out=="FJORD") return(out);
    if (out=="GOAL") return("GOL");
    if (out=="FLEAU") return("FLEO");
    if (out=="HIER") return("IER");
    if (out=="HEU") return("E");
    if (out=="HE") return("E");
    if (out=="OS") return(out);
    if (out=="RIZ") return("RI");
    if (out=="RAZ") return("RA");


    // pré-traitements
    out.replace(QRegExp("OIN[GT]$"),"OIN");  // terminaisons OING -> OIN
    out.replace(QRegExp("E[RS]$"),"E");      // supression des terminaisons infinitifs et participes pluriels
    out.replace(QRegExp("(C|CH)OEU"),"KE");  // pré traitement OEU -> EU
    out.replace(QRegExp("MOEU"),"ME");       // pré traitement OEU -> EU
    // pré traitement OEU OEI -> E
    out.replace(QRegExp("OE([UI]+)([BCDFGHJKLMNPQRSTVWXZ])"),"E\\1\\2");
    out.replace(QRegExp("^GEN[TS]$"),"JAN"); // pré traitement GEN -> JAN


    out.replace(QRegExp("CUEI"),"KEI"); // pré traitement accueil
    // pré traitement AE -> E
    out.replace(QRegExp("([^AEIOUYC])AE([BCDFGHJKLMNPQRSTVWXZ])"),"\\1E\\2");
    out.replace(QRegExp("AE([QS])"),"E\\1");

    // pré-traitement AIE(consonne) -> AI
    out.replace(QRegExp("AIE([BCDFGJKLMNPQRSTVWXZ])"),"AI\\1");

    out.replace(QRegExp("ANIEM"),"ANIM");          // pré traitement NIEM -> NIM
    out.replace(QRegExp("(DRA|TRO|IRO)P$"),"\\1"); // P terminal muet
    out.replace(QRegExp("(LOM)B$"),"\\1");         // B terminal muet
    out.replace(QRegExp("(RON|POR)C$"),"\\1");     // C terminal muet
    out.replace(QRegExp("PECT$"),"PET");           // C terminal muet
    out.replace(QRegExp("ECUL$"),"CU");            // L terminal muet
    out.replace(QRegExp("(CHA|CA|E)M(P|PS)$"),"\\1N"); // P ou PS terminal muet
    out.replace(QRegExp("(TAN|RAN)G$"),"\\1");     // G terminal muet


    // sons YEUX
    out.replace(QRegExp("([^VO])ILAG"),"\\1IAJ");
    out.replace(QRegExp("([^TRH])UIL(AR|E)(.+)"),"\\1UI\\2\\3");
    out.replace(QRegExp("([G])UIL([AEO])"),"\\1UI\\2");
    out.replace(QRegExp("([NSPM])AIL([AEO])"),"\\1AI\\2");

    QStringList convMIn;
    QStringList convMOut;
    convMIn << "DILAI" << "DILON" << "DILER" << "DILEM" << "RILON" << "TAILE" << "GAILET"<< "AILAI" <<"AILAR"
            << "OUILA" << "EILAI" << "EILAR" << "EILER" << "EILEM" << "REILET"<< "EILET" << "AILOL";
    convMOut << "DIAI" << "DION"  << "DIER"  << "DIEM"  << "RION"  << "TAIE"  << "GAIET" << "AIAI" << "AIAR"
             << "OUIA" << "AIAI"  << "AIAR"  << "AIER"  << "AIEM"  << "RAIET" << "EIET"  << "AIOL";

    for(int i = 0; i < convMIn.size(); i++) {
        out.replace(convMIn.at(i),convMOut.at(i));
    }

    out.replace(QRegExp("([^AEIOUY])(SC|S)IEM([EA])"),"\\1\\2IAM\\3"); // IEM -> IAM
    out.replace(QRegExp("^(SC|S)IEM([EA])"),"\\1IAM\\2");              // IEM -> IAM

    // MP MB -> NP NB
    convMIn.clear();
    convMOut.clear();
    convMIn  << "OMB" << "AMB" << "OMP" << "AMP" << "IMB" << "EMP" << "GEMB" << "EMB" << "UMBL" << "CIEN";
    convMOut << "ONB" << "ANB" << "ONP" << "ANP" << "INB" << "ANP" << "JANB" << "ANB" << "INBL" << "SIAN";
    for(int i = 0; i < convMIn.size(); i++) {
        out.replace(convMIn.at(i),convMOut.at(i));
    }

    // Sons en K
    out.replace(QRegExp("^ECHO$"),"EKO");   // cas particulier écho
    out.replace(QRegExp("^ECEUR"),"EKEUR"); // cas particulier écœuré
    // Choléra Chœur mais pas chocolat!
    out.replace(QRegExp("^CH(OG+|OL+|OR+|EU+|ARIS|M+|IRO|ONDR)"),"K\\1");              //En début de mot
    out.replace(QRegExp("(YN|RI)CH(OG+|OL+|OC+|OP+|OM+|ARIS|M+|IRO|ONDR)"),"\\1K\\2"); //Ou devant une consonne
    out.replace(QRegExp("CHS"),"CH");
    out.replace(QRegExp("CH(AIQ)"),"K\\1");
    out.replace(QRegExp("^ECHO([^UIPY])"),"EKO\\1");
    out.replace(QRegExp("ISCH(I|E)"),"ISK\\1");
    out.replace(QRegExp("^ICHT"),"IKT");
    out.replace(QRegExp("ORCHID"),"ORKID");
    out.replace(QRegExp("ONCHIO"),"ONKIO");
    out.replace(QRegExp("ACHIA"),"AKIA");          // retouche ACHIA -> AKIA
    out.replace(QRegExp("([^C])ANICH"),"\\1ANIK"); // ANICH -> ANIK 	1/2
    out.replace(QRegExp("OMANIK"),"OMANICH");      // cas particulier 	2/2
    out.replace(QRegExp("ACHY([^D])"),"AKI\\1");
    out.replace(QRegExp("([AEIOU])C([BDFGJKLMNPQRTVWXZ])"),"\\1K\\2"); // voyelle, C, consonne sauf H

    convMIn.clear();
    convMOut.clear();
    convMIn  << "EUCHA" << "YCHIA" << "YCHA"  <<"YCHO"   << "YCHED" << "ACHEO" << "RCHEO"   << "RCHES"
             << "ECHN"  << "OCHTO" << "CHORA" <<"CHONDR" << "CHORE" << "MACHM" << "BRONCHO" << "LICHOS" << "LICHOC";
    convMOut << "EKA"   << "IKIA"  << "IKA"   << "IKO"   << "IKED"  << "AKEO"  << "RKEO"    << "RKES"
             << "EKN"   << "OKTO"  << "KORA"  << "KONDR" << "KORE"  << "MAKM"  << "BRONKO"  << "LIKOS" << "LIKOC";
    for(int i = 0; i < convMIn.size(); i++) {
        out.replace(convMIn.at(i),convMOut.at(i));
    }

    // Weuh (perfectible)
    convMIn.clear();
    convMOut.clear();
    convMIn  << "WA" << "WO" << "WI"  << "WHI" << "WHY" << "WHA" << "WHO";
    convMOut << "OI" << "O"  << "OUI" << "OUI" << "OUI" << "OUA" << "OU";
    for(int i = 0; i < convMIn.size(); i++) {
        out.replace(convMIn.at(i),convMOut.at(i));
    }

    // Gueu, Gneu, Jeu et quelques autres
    convMIn.clear();
    convMOut.clear();
    convMIn << "GNES"  << "GNET"  << "GNER"  << "GNE"  << "GI"    << "GNI"  << "GNA"  << "GNOU"  << "GNUR" << "GY"    << "OUGAIN"
            << "AGEOL" << "AGEOT" << "GEOLO" << "GEOM" << "GEOP"  << "GEOG" << "GEOS" << "GEORG" << "GEOR" << "NGEOT" << "UGEOT" << "GEOT" << "GEOD" << "GEOC" << "GEO" << "GEA" << "GE"
            << "QU"    << "Q"     << "CY"    << "CI"   << "CN"    << "ICM"  << "CEAT" << "CE"
            << "CR"    << "CO"    << "CUEI"  << "CU"   << "VENCA" << "CA"   << "CS"   << "CLEN"  << "CL"   << "CZ"    << "CTIQ"
            << "CTIF"  << "CTIC"  << "CTIS"  << "CTIL" << "CTIO"  << "CTI"  << "CTU"  << "CTE"   << "CTO"  << "CTR"   << "CT"    << "PH"   << "TH"
            << "OW"    << "LH"    << "RDL"   << "CHLO" << "CHR"   << "PTIA";
    convMOut << "NIES" << "NIET"  << "NIER"  << "NE"   << "JI"    << "NI"   << "NIA"  << "NIOU"  << "NIUR" << "JI"    << "OUGIN"
             << "AJOL" << "AJOT"  << "JEOLO" << "JEOM" << "JEOP"  << "JEOG" << "JEOS" << "JORJ"  << "JEOR" << "NJOT"  << "UJOT" << "JEOT" << "JEOD" << "JEOC" << "JO" << "JA"    <<"JE"
             << "K"    << "K"     << "SI"    << "SI"   << "KN"    << "IKM"  << "SAT"  << "SE"
             << "KR"   << "KO"    << "KEI"   << "KU"   << "VANSA" << "KA"   << "KS"   << "KLAN" << "KL"    << "KZ"    << "KTIK"
             << "KTIF" << "KTIS"  << "KTIS"  << "KTIL" << "KSIO"  << "KTI"  << "KTU"  << "KTE"  << "KTO"   << "KTR"   << "KT"   << "F"    << "T"
             << "OU"   << "L"     << "RL"    << "KLO"  << "KR"    << "PSIA";
    for(int i = 0; i < convMIn.size(); i++) {
        out.replace(convMIn.at(i),convMOut.at(i));
    }

    out.replace(QRegExp("GU([^RLMBSTPZN])"),"G\\1"); // Gueu !
    out.replace(QRegExp("GNO([MLTNRKG])"),"NIO\\1"); // GNO ! Tout sauf S pour gnos
    out.replace(QRegExp("GNO([MLTNRKG])"),"NIO\\1"); // bis -> gnognotte! Si quelqu'un sait le faire en une seule regexp...

    // TI -> SI v2.0
    convMIn.clear();
    convMOut.clear();
    convMIn  << "BUTIE" << "BUTIA"  << "BATIA" << "ANTIEL"  << "RETION"  << "ENTIEL" << "ENTIAL" << "ENTIO" << "ENTIAI" << "UJETION" << "ATIEM" << "PETIEN"
              << "CETIE" << "OFETIE" << "IPETI" << "LBUTION" << "BLUTION" << "LETION" << "LATION" << "SATIET";
    convMOut << "BUSIE" << "BUSIA"  << "BASIA" << "ANSIEL"  << "RESION"  << "ENSIEL" << "ENSIAL" << "ENSIO" << "ENSIAI" << "UJESION" << "ASIAM" << "PESIEN"
              << "CESIE" << "OFESIE" << "IPESI" << "LBUSION" << "BLUSION" << "LESION" << "LASION" << "SASIET";
    for(int i = 0; i < convMIn.size(); i++) {
        out.replace(convMIn.at(i),convMOut.at(i));
    }

    out.replace(QRegExp("(.+)ANTI(AL|O)"),"\\1ANSI\\2");  // sauf antialcoolique, antialbumine, antialarmer, ...
    out.replace(QRegExp("(.+)INUTI([^V])"),"\\1INUSI\\2"); // sauf inutilité, inutilement, diminutive, ...
    out.replace(QRegExp("([^O])UTIEN"),"\\1USIEN");       // sauf soutien, ...
    out.replace(QRegExp("([^DE])RATI[E]$"),"\\1RASI"); // sauf xxxxxcratique, ...

    // TIEN TION -> SIEN SION v3.1
    out.replace(QRegExp("([^SNEU]|KU|KO|RU|LU|BU|TU|AU)T(IEN|ION)"),"\\1S\\2");

    // H muet
    out.replace(QRegExp("([^CS])H"),"\\1"); // H muet
    out.replace(QRegExp("ESH"),"ES");       // H muet
    out.replace(QRegExp("NSH"),"NS");       // H muet
    out.replace(QRegExp("SH"),"CH");        // ou pas !

    // NASALES
    convMIn.clear();
    convMOut.clear();
    convMIn  << "OMT" << "IMB" << "IMP" << "UMD" << "TIENT" << "RIENT" << "DIENT" << "IEN"
             << "YMU" << "YMO" << "YMA" << "YME" << "YMI"   << "YMN"   << "YM"    << "AHO" << "FAIM" << "DAIM" << "SAIM" << "EIN" << "AINS";
    convMOut << "ONT" << "INB" << "INP" << "OND" << "TIANT" << "RIANT" << "DIANT" << "IN"
             << "IMU" << "IMO" << "IMA" << "IME" << "IMI"   << "IMN"   << "IN"    << "AO"  << "FIN"  << "DIN"  << "SIN"  << "AIN" << "INS";
    for(int i = 0; i < convMIn.size(); i++) {
        out.replace(convMIn.at(i),convMOut.at(i));
    }

    // AIN -> IN v2.0
    out.replace(QRegExp("AIN$"),"IN");
    out.replace(QRegExp("AIN([BTDK])"),"IN\\1");
    // UN -> IN
    out.replace(QRegExp("([^O])UND"),"\\1IND"); // aucun mot français ne commence par UND!
    out.replace(QRegExp("([JTVLFMRPSBD])UN([^IAE])"),"\\1IN\\2");
    out.replace(QRegExp("([JTVLFMRPSBD])UN$"),"\\1IN");
    out.replace(QRegExp("RFUM$"),"RFIN");
    out.replace(QRegExp("LUMB"),"LINB");
    // EN -> AN
    out.replace(QRegExp("([^BCDFGHJKLMNPQRSTVWXZ])EN"),"\\1AN");
    out.replace(QRegExp("([VTLJMRPDSBFKNG])EN([BRCTDKZSVN])"),"\\1AN\\2"); // deux fois pour les motifs recouvrants malentendu, pendentif, ...
    out.replace(QRegExp("([VTLJMRPDSBFKNG])EN([BRCTDKZSVN])"),"\\1AN\\2"); // si quelqu'un sait faire avec une seule regexp!
    out.replace(QRegExp("^EN([BCDFGHJKLNPQRSTVXZ]|CH|IV|ORG|OB|UI|UA|UY)"),"AN\\1");
    out.replace(QRegExp("(^[JRVTH])EN([DRTFGSVJMP])"),"\\1AN\\2");
    out.replace(QRegExp("SEN([ST])"),"SAN\\1");
    out.replace(QRegExp("^DESENIV"),"DESANIV");

    out.replace(QRegExp("([^M])EN(UI)"),"\\1AN\\2");
    out.replace(QRegExp(""),"");
    out.replace(QRegExp("(.+[JTVLFMRPSBD])EN([JLFDSTG])"),"\\1AN\\2");
    // EI -> AI
    out.replace(QRegExp("([VSBSTNRLPM])E[IY]([ACDFRJLGZ])"),"\\1AI\\2");

    // Histoire d'Ô
    convMIn.clear();
    convMOut.clear();
    convMIn  << "EAU" << "EU" << "Y" << "EOI" << "JEA" << "OIEM" << "OUANJ" << "OUA" << "OUENJ";
    convMOut << "O"   << "E"  << "I" << "OI"  << "JA"  << "OIM"  << "OUENJ" << "OI"  << "OUANJ";
    for(int i = 0; i < convMIn.size(); i++) {
        out.replace(convMIn.at(i),convMOut.at(i));
    }

    out.replace(QRegExp("AU([^E])"),"O\\1"); // AU sans E qui suit

    // Les retouches!
    out.replace(QRegExp("^BENJ"),"BINJ");             // retouche BENJ -> BINJ
    out.replace(QRegExp("RTIEL"),"RSIEL");            // retouche RTIEL -> RSIEL
    out.replace(QRegExp("PINK"),"PONK");              // retouche PINK -> PONK
    out.replace(QRegExp("KIND"),"KOND");              // retouche KIND -> KOND
    out.replace(QRegExp("KUM(N|P)"),"KON\\1");        // retouche KUMN KUMP
    out.replace(QRegExp("LKOU"),"LKO");               // retouche LKOU -> LKO
    out.replace(QRegExp("EDBE"),"EBE");               // retouche EDBE pied-buf
    out.replace(QRegExp("ARCM"),"ARKM");              // retouche SCH -> CH
    out.replace(QRegExp("SCH"),"CH");                 // retouche SCH -> CH
    out.replace(QRegExp("^OINI"),"ONI");              // retouche début OINI -> ONI
    out.replace(QRegExp("([^NDCGRHKO])APT"),"\\1AT"); // retouche APT -> AT
    out.replace(QRegExp("([L]|KON)PT"),"\\1T");       // retouche LPT -> LT
    out.replace(QRegExp("OTB"),"OB");                 // retouche OTB -> OB (hautbois)
    out.replace(QRegExp("IXA"),"ISA");                // retouche IXA -> ISA
    out.replace(QRegExp("TG"),"G");                   // retouche TG -> G
    out.replace(QRegExp("^TZ"),"TS");                 // retouche début TZ -> TS
    out.replace(QRegExp("PTIE"),"TIE");               // retouche PTIE -> TIE
    out.replace(QRegExp("GT"),"T");                   // retouche GT -> T
    out.replace("ANKIEM","ANKILEM");                  // retouche tranquillement
    out.replace(QRegExp("(LO|RE)KEMAN"),"\\1KAMAN");  // KEMAN -> KAMAN
    out.replace(QRegExp("NT(B|M)"),"N\\1");           // retouche TB -> B  TM -> M
    out.replace(QRegExp("GSU"),"SU");                 // retouche GS -> SU
    out.replace(QRegExp("ESD"),"ED");                 // retouche ESD -> ED
    out.replace(QRegExp("LESKEL"),"LEKEL");           // retouche LESQUEL -> LEKEL
    out.replace(QRegExp("CK"),"K");                   // retouche CK -> K

    // Terminaisons
    out.replace(QRegExp("USIL$"),"USI");              // terminaisons USIL -> USI
    out.replace(QRegExp("X$|[TD]S$|[DS]$"),"");       // terminaisons TS DS LS X T D S...  v2.0
    out.replace(QRegExp("([^KL]+)T$"),"\\1");         // sauf KT LT terminal
    out.replace(QRegExp("^[H]"),"");                  // H pseudo muet en début de mot, je sais, ce n'est pas une terminaison
    sauvePourMotsTresCourtsBis = out;                 // on sauve le code (utilisé pour les mots très courts)
    out.replace(QRegExp("TIL$"),"TI");                   // terminaisons TIL -> TI
    out.replace(QRegExp("LC$"),"LK");                    // terminaisons LC -> LK
    out.replace(QRegExp("L[E]?[S]?$"),"L");              // terminaisons LE LES -> L
    out.replace(QRegExp("(.+)N[E]?[S]?$"),"\\1N");       // terminaisons NE NES -> N
    out.replace(QRegExp("EZ$"),"E");                     // terminaisons EZ -> E
    out.replace(QRegExp("OIG$"),"OI");                   // terminaisons OIG -> OI
    out.replace(QRegExp("OUP$"),"OU");                   // terminaisons OUP -> OU
    out.replace(QRegExp("([^R])OM$"),"\\1ON");           // terminaisons OM -> ON sauf ROM
    out.replace(QRegExp("LOP$"),"LO");                   // terminaisons LOP -> LO
    out.replace(QRegExp("NTANP$"),"NTAN");               // terminaisons NTANP -> NTAN
    out.replace(QRegExp("TUN$"),"TIN");                  // terminaisons TUN -> TIN
    out.replace(QRegExp("AU$"),"O");                     // terminaisons AU -> O
    out.replace(QRegExp("EI$"),"AI");                    // terminaisons EI -> AI
    out.replace(QRegExp("R[DG]$"),"R");                  // terminaisons RD RG -> R
    out.replace(QRegExp("ANC$"),"AN");                   // terminaisons ANC -> AN
    out.replace(QRegExp("KROC$"),"KRO");                 // terminaisons C muet de CROC, ESCROC
    out.replace(QRegExp("HOUC$"),"HOU");                 // terminaisons C muet de CAOUTCHOUC
    out.replace(QRegExp("OMAC$"),"OMA");                 // terminaisons C muet de ESTOMAC (mais pas HAMAC)
    out.replace(QRegExp("([J])O([NU])[CG]$"),"\\1O\\2"); // terminaisons C et G muet de OUC ONC OUG
    out.replace(QRegExp("([^GTR])([AO])NG$"),"\\1\\2N"); // terminaisons G muet ANG ONG sauf GANG GONG TANG TONG
    out.replace(QRegExp("UC$"),"UK");                    // terminaisons UC -> UK
    out.replace(QRegExp("AING$"),"IN");                  // terminaisons AING -> IN
    out.replace(QRegExp("([EISOARN])C$"),"\\1K");        // terminaisons C -> K
    out.replace(QRegExp("([ABD-MO-Z]+)[EH]+$"),"\\1");   // terminaisons E ou H sauf pour C et N
    out.replace(QRegExp("EN$"),"AN");                    // terminaisons EN -> AN (difficile à faire avant sans avoir des soucis) Et encore, c'est pas top!
    out.replace(QRegExp("(NJ)EN$"),"\\1AN");             // terminaisons EN -> AN
    out.replace(QRegExp("^PAIEM"),"PAIM");               // PAIE -> PAI
    out.replace(QRegExp("([^NTB])EF$"),"\\1");            // F muet en fin de mot

    out.replace(QRegExp("(.)\\1"),"\\1");                 // supression des répétitions (suite à certains remplacements)

    // cas particuliers, bah au final, je n'en ai qu'un ici
    convMIn.clear();
    convMOut.clear();
    convMIn  << "FUEL";
    convMOut << "FIOUL";

    for(int i = 0; i < convMIn.size(); i++) {
        out.replace(convMIn.at(i),convMOut.at(i));
    }

    // Ce sera le seul code retourné à une seule lettre!
    if (out == "O") {
        return out;
    }

    // seconde chance sur les mots courts qui ont souffert de la simplification
    if (out.size() < 2 ) {
        // Sigles ou abréviations
        if(sauvePourMotsTresCourts.contains(QRegExp("[BCDFGHJKLMNPQRSTVWXYZ][BCDFGHJKLMNPQRSTVWXYZ][BCDFGHJKLMNPQRSTVWXYZ][BCDFGHJKLMNPQRSTVWXYZ]*"))) {
            return sauvePourMotsTresCourts;
        }

        if(sauvePourMotsTresCourts.contains(QRegExp("[RFMLVSPJDF][AEIOU]"))) {
            if (sauvePourMotsTresCourts.size() == 3) {
                return sauvePourMotsTresCourts.left(2);// mots de trois lettres supposés simples
            }
            if (sauvePourMotsTresCourts.size() == 4) {
                return sauvePourMotsTresCourts.left(3);// mots de quatre lettres supposés simples
            }
        }

        if (sauvePourMotsTresCourtsBis.size() > 1) {
            return sauvePourMotsTresCourtsBis;
        }
    }

    if (out.size() > 1) {
        return out.left(16); // Je limite à 16 caractères mais vous faites comme vous voulez!
    }
    else {
        return "";
    }
}
