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 #?
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());
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);
}
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())
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.
Tu peux le faire:
var hChars = new char[] {...};
var result = new string(yourString.Where(c => !hChars.Contains(c)).ToArray());
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.
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.
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