web-dev-qa-db-fra.com

Suppression des caractères cachés dans les chaînes

Mon problème: 

J'ai une application .NET qui envoie des newsletters par courrier électronique. Lorsque les bulletins sont affichés dans Outlook, Outlook affiche un point d’interrogation à la place du caractère masqué qu’il ne peut pas reconnaître. Ces caractères cachés proviennent d'utilisateurs finaux qui copient et collent le code HTML qui compose les bulletins d'information dans un formulaire et le soumettent. Un c # trim () supprime ces caractères masqués s'ils se produisent à la fin ou au début de la chaîne. Lorsque la newsletter est consultée dans gmail, gmail fait un bon travail en les ignorant. Lorsque je colle ces caractères masqués dans un document Word et que j'active l'option «Afficher les marques de paragraphe et les symboles masqués», les symboles apparaissent sous la forme d'un rectangle à l'intérieur d'un rectangle plus grand. De plus, le texte qui compose les newsletters peut être dans n'importe quelle langue. Accepter les caractères Unicode est donc indispensable. J'ai essayé de parcourir la chaîne pour détecter le caractère, mais la boucle ne le reconnaît pas et le passe au-dessus. Demander également à l'utilisateur final de coller le code HTML dans le bloc-notes avant de le soumettre est hors de question. 

Ma question:
Comment puis-je détecter et éliminer ces caractères cachés en utilisant C #? 

19
bradley4

Vous pouvez supprimer tous les caractères de contrôle de votre chaîne d'entrée avec quelque chose comme ceci:

string input; // this is your input string
string output = new string(input.Where(c => !char.IsControl(c)).ToArray());

Voici la documentation pour la méthode IsControl().

Ou si vous souhaitez conserver uniquement des lettres et des chiffres, vous pouvez également utiliser la fonction IsLetter et IsDigit

string output = new string(input.Where(c => char.IsLetter(c) || char.IsDigit(c)).ToArray());
58
Yannick Blondeau

J'utilise généralement cette expression régulière pour remplacer tous les caractères non imprimables.

En passant, la plupart des gens pensent que les tabulations, les sauts de ligne et les retours à la ligne ne sont pas des caractères imprimables, mais ce n'est pas le cas pour moi. 

Alors voici l'expression:

string output = Regex.Replace(input, @"[^\u0009\u000A\u000D\u0020-\u007E]", "*");
  • ^ signifie s'il s'agit de l'un des éléments suivants:
  • \u0009 est onglet 
  • \u000A est un saut de ligne
  • \u000D est un retour chariot
  • \u0020-\u007E signifie tout, de l'espace au ~, c'est-à-dire tout en ASCII.

Voir le tableau ASCII si vous souhaitez apporter des modifications. Rappelez-vous que tous les caractères non-ASCII seraient supprimés. 

Pour tester ci-dessus, vous pouvez créer une chaîne par vous-même comme ceci:

    string input = string.Empty;

    for (int i = 0; i < 255; i++)
    {
        input += (char)(i);
    }
16
Mubashar Ahmad
new string(input.Where(c => !char.IsControl(c)).ToArray());

IsControl manque certains caractères de contrôle, tels que la marque de gauche à droite (LRM) (le caractère qui se cache généralement dans une chaîne lors du copier/coller). Si vous êtes sûr que votre chaîne ne comporte que des chiffres, vous pouvez utiliser IsLetterOrDigit.

new string(input.Where(c => char.IsLetterOrDigit(c)).ToArray())

Si votre chaîne a des caractères spéciaux, alors

new string(input.Where(c => c < 128).ToArray())
5
shanmuga raja

Ce qui a le mieux fonctionné pour moi est:

string result = new string(value.Where(c =>  char.IsLetterOrDigit(c) || (c >= ' ' && c <= byte.MaxValue)).ToArray());

Lorsque je m'assure que le caractère est une lettre ou un chiffre, afin de ne pas ignorer les lettres autres qu'anglais, ou s'il ne s'agit pas d'une lettre, je vérifie s'il s'agit d'un caractère ascii supérieur ou égal à Space pour être sûr J'ignore certains caractères de contrôle, cela m'assure de ne pas ignorer la ponctuation.

Certains suggèrent d'utiliser IsControl pour vérifier si le caractère n'est pas imprimable ou non, mais cela ignore la marque de gauche à droite, par exemple. 

3
Igor Meszaros

Tu peux le faire:

var hChars = new char[] {...};
var result = new string(yourString.Where(c => !hChars.Contains(c)).ToArray());
3
aush

Si vous connaissez ces caractères, vous pouvez utiliser string.Replace:

newString = oldString.Replace("?", "");

où "?" représente le personnage que vous voulez déshabiller.

L'inconvénient de cette approche est que vous devez effectuer plusieurs fois cet appel si vous souhaitez supprimer plusieurs caractères.

1
ChrisF

Cela fait un moment mais on n'a pas encore répondu à cette question. 

Comment incluez-vous le contenu HMTL dans le code d'envoi? Si vous le lisez depuis un fichier, vérifiez le codage du fichier. Si vous utilisez UTF-8 avec une signature (le nom varie légèrement d’un éditeur à l’autre), le caractère étrange au début du message risque de l’être.

0
SimSimY

string output = new string (input.Where (c =>! char.IsControl (c)). ToArray ()); Cela résoudra sûrement le problème. J'avais un caractère de substitution non imprimable (ASCII 26) dans une chaîne qui entraînait la rupture de mon application et cette ligne de code supprimait les caractères

0
Niraj Kheria