Problème avec les regex

a marqué ce sujet comme résolu.

Bonjour à tous,

je suis en train de réaliser le défi de Clem de ce mois et je suis pour l'instant à l'étape 0, faire une fonction qui prépare l'input au décryptage. J'ai écris mon code (dispo sur Github et tous marche sauf le remplacement des caractères accentué qui fait n'importe quoi, j'utilise les regex pour le faire mais sa ne marche pas vraiment comme je le veux, par exemple ce caractère '’' est remplacé par un A, un E, un U alors qu'il devait juste être supprimé, et aussi si il y a (par example) un 'é' dans le message, au lieu d'être remplacé par un seul et unique E, il est remplacé par 2.

voilà mon problème, j'espère que vous pourrez m'aidez et je vous remercie d'avance :)

+0 -0

Du coup j'ai mis mes regex en wregex, donc par échéance mon input en wstring sauf que std::getline est pas content et me dis

1
2
/home/ludovic/workspace/C++/Defi_de_Clem_02-2016/src/main.cpp:23:37: erreur : no matching function for call to ‘getline(std::istream&, std::__cxx11::wstring&)’
     std::getline<wchar_t>(cin, input);

alors que d'après la declaration sur cppreference ça devrait marcher. Une idée ?

+0 -0

Après des recherches plus approfondis je suis tombé là dessus lien, donc le problème ne vient pas des strings mais des regex car un é est composé de plusieurs caractère. Du coup j'ai reécris cette partie de la fonction comme ça

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
    std::array<std::array<std::string, 2>, 5> const toChange = {
        {"éêèëÉÈÊË", "E"},
        {"àâÀÂ",     "A"},
        {"ûùÛÙ",     "U"},
        {"çÇ",       "C"},
        {"œŒ",       "OE"}
    };

    for(auto const &pair: toChange)
    {
        for(auto const &c: pair[0])
        {
            std::replace(input.begin(), input.end(), c, pair[1]);
        }
    }
    input = std::regex_replace(input, std::regex(L"[^A-Za-z ]"), "");

sauf que le compilateur me renvoye cette erreur erreur : too many initializers for ‘const std::array<std::array<std::__cxx11::basic_string<char>, 2ul>, 5ul>’ qui d'après mes recherche veut dire que j'ai défini plus de variable que peut en contenir mon array alors que j'ai beau regarder le code, pour moi c'est bon.

+0 -0

Double accolades pour initialiser un std::array:

1
2
3
toChange{{
...
}};

Par contre, cette solution est totalement bogué. En plus de ne pourvoir compiler, Elle ne remplace par les caractères, mais les octets constituant les caractères ; "é" devient "EE" ou "EEE".

Autre point, il y plusieurs manière de faire un é en utf-8, le code dédié ou la combinaison accent+lettre.

Regarde la fonction std::regex::imbue (ex: rgx.imbue(std::locale("fr_FR.UTF8"))).

Effectivement, imbue ne cgange pas grand chose et j'ai des exceptions avec les char16_t.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#include <iostream> 
#include <string> 
#include <regex> 
#include <locale> 
#include <codecvt>

int main()
{
  std::string input;
  std::getline(std::cin, input);

  std::wstring_convert<std::codecvt_utf8<wchar_t>, wchar_t> ucs2conv;

  std::wstring utf8 = ucs2conv.from_bytes(input);
  std::basic_regex<wchar_t> rgx;
  rgx.assign(utf8);

  wchar_t s[] = L"éqÉ";
  std::regex_replace(
    std::ostreambuf_iterator<wchar_t>(std::wcout)
  , std::begin(s)
  , std::end(s)
  , rgx, L"E"
  );
}

commande: ./a.out <<<'[éêèëÉÈÊË]'

Sortie:

EqE

+0 -0

C'est peut-être aussi un signe pour dire que l'expression régulière n'est peut-être pas ce qu'il faut utiliser dans ce cas-ci. (:

dab

Certe, mais je ne vois pas quoi utiliser d'autre que les regex et l'autre technique que j'ai cité plus haut. :(

+0 -0

Il faut déjà se poser la question : est-ce que ça a du sens de vouloir transcoder des caractères de façon arbitraire ? Est-ce qu'il ne faudrait pas simplement refuser les entrées qui ne contiennent pas des caractères que tu sais comment encoder et décoder ? Ou alors, est-ce qu'il ne faudrait peut-être pas mieux définir un encodage sur l'ensemble des caractères disponibles ? (ce qui est au final équivalent surjection après à ce que je disais avant)

Il faut déjà se poser la question : est-ce que ça a du sens de vouloir transcoder des caractères de façon arbitraire ? Est-ce qu'il ne faudrait pas simplement refuser les entrées qui ne contiennent pas des caractères que tu sais comment encoder et décoder ? Ou alors, est-ce qu'il ne faudrait peut-être pas mieux définir un encodage sur l'ensemble des caractères disponibles ? (ce qui est au final équivalent surjection après à ce que je disais avant)

dab

Je comprends pas trop ou tu veux en venir.

+0 -0
Connectez-vous pour pouvoir poster un message.
Connexion

Pas encore membre ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte