2009-05-11 6 views
4

Existe-t-il un moyen rapide (sans avoir à faire explicitement une boucle sur chaque caractère d'une chaîne) et de l'enlever ou de le conserver. Dans Visual FoxPro, il existe une fonction CHRTRAN() qui le fait génial. C'est sur un remplacement de 1: 1 caractères, mais si aucun caractère dans la position de remplacement, son dépouillé de la chaîne finale. ExC# Dénuder/convertir un ou plusieurs caractères

CHRTRAN ("Ce sera un test", "il", "X")

retournera

"Thxs wXll être un es"

avis l'original "i" est converti en "X", et en minuscule "t" est effacé.

J'ai regardé le remplacement pour l'intention semblable, mais n'ai pas vu une option pour remplacer avec rien.

Je cherche à créer des routines génériques pour valider plusieurs origines de données qui ont différents types de restrictions d'entrée. Certaines des données peuvent provenir de sources externes, donc ce n'est pas seulement une validation d'entrée de zone de texte que je dois tester.

Merci

+1

CHRTRAN est une API bizarre. –

+0

@Greg D - Seulement si vous n'avez jamais travaillé avec FoxPro. Je crois que TRANSLATE dans Oracle PL/SQL fonctionne de la même manière. –

+0

Ou l'opérateur tr /// d de Perl si la mémoire le permet. –

Répondre

5

Voici ma dernière fonction et fonctionne parfaitement comme prévu.

public static String ChrTran(String ToBeCleaned, 
          String ChangeThese, 
          String IntoThese) 
{ 
    String CurRepl = String.Empty; 
    for (int lnI = 0; lnI < ChangeThese.Length; lnI++) 
    { 
     if (lnI < IntoThese.Length) 
     CurRepl = IntoThese.Substring(lnI, 1); 
     else 
     CurRepl = String.Empty; 

     ToBeCleaned = ToBeCleaned.Replace(ChangeThese.Substring(lnI, 1), CurRepl); 
    } 
    return ToBeCleaned; 
} 
+1

Je sais que c'est un très vieux fil, mais cette fonction ne fonctionne pas comme prévu. Cela ne fonctionne que si ChangeThese/IntoThese ne contient pas les mêmes caractères. C'est parce que la fonction String.Replace remplacera plusieurs caractères plusieurs fois dans certaines conditions. Si vous prenez ChrTran ("Alfabet", "ABab12", "21baBA"), vous vous attendez à ce que la sortie soit "2lfbaet". La sortie réelle est cependant "Alfaaet". Le "A" sera remplacé par un "2", mais plus tard, "2" sera remplacé à nouveau par "A". Vous devez parcourir la chaîne d'entrée et remplacer char par char pour éviter les remplacements doubles. – RiptoR

+0

@RiptoR, vous semblez avoir un bon point, mais pas de la manière initialement prévue la routine à travailler. Dans l'utilisation prévue, je n'aurais pas fait les mêmes lettres dans les deux chaînes, mais dûment noté. – DRapp

+0

Mes excuses. Je suis tombé sur ceci en cherchant un équivalent .NET des fonctions translate/maketrans de Python donc je pensais en termes de fonctionnement de ces fonctions. – RiptoR

9

Tout ce que vous avez besoin est quelques appels à String.Replace().

string s = "This will be a test"; 
s = s.Replace("i", "X"); 
s = s.Replace("t", ""); 

Notez que Remplacer() retours une nouvelle chaîne. Cela ne modifie pas la chaîne elle-même.

5

Est-ce-que vous voulez?

"This will be a test".Replace("i", "X").Replace("t", String.Empty) 

Voici une implémentation simple de la fonction CHRTRAN - il ne fonctionne pas si la chaîne contient \0 et est tout à fait désordre. Vous pourriez écrire un plus joli en utilisant des boucles, mais je voulais juste l'essayer en utilisant LINQ.

public static String ChrTran(String input, String source, String destination) 
{ 
    return source.Aggregate(
     input, 
     (current, symbol) => current.Replace(
      symbol, 
      destination.ElementAtOrDefault(source.IndexOf(symbol))), 
     preResult => preResult.Replace("\0", String.Empty)); 
} 

Et vous pouvez l'utiliser.

// Returns "ThXs wXll be a es" 
String output = ChrTran("This will be a test", "it", "X"); 

Juste pour avoir une solution propre - même sans LINQ et travailler pour les \0 cas aussi, et il est presque en place à cause de l'utilisation d'un StringBuilder mais ne modifiera pas l'entrée, bien sûr.

public static String ChrTran(String input, String source, String destination) 
{ 
    StringBuilder result = new StringBuilder(input); 

    Int32 minLength = Math.Min(source.Length, destination.Length); 

    for (Int32 i = 0; i < minLength; i++) 
    { 
     result.Replace(source[i], destination[i]); 
    } 

    for (Int32 i = minLength; i < searchPattern.Length; i++) 
    { 
     result.Replace(source[i].ToString(), String.Empty); 
    } 

    return result.ToString(); 
} 

La gestion des références nulles est manquante. Inspiré par la solution de tvanfosson, j'ai donné un second coup à LINQ.

public static String ChrTran(String input, String source, String destination) 
{ 
    return new String(input. 
     Where(symbol => 
      !source.Contains(symbol) || 
      source.IndexOf(symbol) < destination.Length). 
     Select(symbol => 
      source.Contains(symbol) 
       ? destination[source.IndexOf(symbol)] 
       : symbol). 
     ToArray()); 
} 
+0

Je ne sais pas pourquoi le remplacement ne fonctionnait pas pour moi à l'origine, mais le String.Empty a fonctionné ... Bien que je ne sois pas dans Linq, ce que vous aviez dans le contexte était un mécanisme de bouclage similaire que j'aurais fait 't un équivalent direct ... Je suis sur mon chemin ... Merci – DRapp

3

Pour "remplacer par rien", il suffit de remplacer par une chaîne vide. Cela vous donnera:

String str = "This will be a test"; 
str = str.Replace("i", "X"); 
str = str.Replace("t",""); 
3

Une version plus générale comme une extension de chaîne. Comme les autres, ceci n'effectue pas de traduction car les chaînes sont immuables en C#, mais renvoie une nouvelle chaîne avec les remplacements spécifiés.

public static class StringExtensions 
{ 
    public static string Translate(this string source, string from, string to) 
    { 
     if (string.IsNullOrEmpty(source) || string.IsNullOrEmpty(from)) 
     { 
      return source; 
     } 

     return string.Join("", source.ToCharArray() 
            .Select(c => Translate(c, from, to)) 
            .Where(c => c != null) 
            .ToArray()); 
    } 

    private static string Translate(char c, string from, string to) 
    { 
     int i = from != null ? from.IndexOf(c) : -1; 
     if (i >= 0) 
     { 
      return (to != null && to.Length > i) 
         ? to[i].ToString() 
         : null; 
     } 
     else 
     { 
      return c.ToString(); 
     } 
    } 
} 
3

Ceci est un cas où je pense que l'utilisation de LINQ complique le sujet. C'est simple et précis:

private static string Translate(string input, string from, string to) 
{ 
    StringBuilder sb = new StringBuilder(); 
    foreach (char ch in input) 
    { 
     int i = from.IndexOf(ch); 
     if (from.IndexOf(ch) < 0) 
     { 
      sb.Append(ch); 
     } 
     else 
     { 
      if (i >= 0 && i < to.Length) 
      { 
       sb.Append(to[i]); 
      } 
     } 
    } 
    return sb.ToString(); 
} 
-1

 public static string ChrTran(string cSearchIn, string cSearchFor, string cReplaceWith) 
     { 
      string result = ""; 
      dynamic inArray = cSearchIn.ToCharArray(); 
      foreach (var caracter in inArray) 
      { 
       int position = cSearchFor.IndexOf(caracter); 
       result = result + cReplaceWith.Substring(position, 1);

} return result; }</pre>
Questions connexes