2009-05-11 9 views
4

文字列内の各文字を明示的にループする必要はなく、ストリッピングまたは保持の方法がありますか。 Visual FoxProには、CHRTRAN()関数が用意されています。それは1:1の文字置換であるが、代替位置に文字がない場合、その文字列は最後の文字列から取り除かれる。例C#1つまたは複数の文字のストリッピング/変換

CHRTRAN

お知らせオリジナルの "I" "ESもwXll ThXs"

を返します( "それは"、 "X" は、 "これはテストになります") "X"に変換され、小文字の "t"が取り除かれます。

私は同様の意図のためにreplaceを見ましたが、何も置き換えないという選択肢はありませんでした。

さまざまなタイプの入力制限を持つデータの複数の起点を検証するための汎用ルーチンを作成したいと考えています。一部のデータは外部ソースからのものである可能性があるため、テストする必要のあるテキストボックス入力の検証だけではありません。

おかげ

+1

CHRTRANは奇妙なAPIです。 –

+0

@ Greg D - あなたがFoxProで働いたことがない人のみ。私は、OracleのPL/SQLのTRANSLATEも同じように動作すると信じています。 –

+0

またはメモリが使用されている場合はPerlのtr /// d演算子。 –

答えて

5

これは私の最終的な機能であり、期待通りに機能します。

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

私はこれが非常に古いスレッドだと知っていますが、この関数は期待どおりに動作しません。 ChangeThese/IntoTheseに同じ文字が含まれていない場合にのみ機能します。これは、特定の条件下でString.Replace関数が特定の文字を複数回置き換えるためです。 ChrTran( "Alfabet"、 "ABab12"、 "21baBA")を取ると、出力は "2lfbaet"になると予想されます。しかし、実際の出力は "Alfaaet"です。 "A"は "2"に置き換えられますが、後で "2"は再び "A"に置き換えられます。 二重置換を防ぐには、入力文字列をループし、charをcharに置き換える必要があります。 – RiptoR

+0

@RiptoR、あなたは良いポイントを持っているように見えますが、もともとルーチンを動作させる意図はありませんでした。意図された使用法では、私は両方の文字列で同じ文字を使っていなかったでしょうが、正当な注目がありました。 – DRapp

+0

謝罪します。 Pythonのtranslate/maketrans関数の.NETに相当するものを探していたので、私はこれらの関数の仕組みを考えていました。 – RiptoR

9

必要なのはString.Replace()への呼び出しのカップルです。

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

(置き換え注)戻り新しい文字列。文字列自体は変更されません。

5

これは何をしますか?ここで

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

CHRTRAN機能の簡単な実装です - 文字列が\0が含まれており、非常に厄介であるならば、それは動作しません。あなたはループを使ってより良いものを書くことができましたが、私は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)); 
} 

それを使用することができます。

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

ただ、きれいな解決策持っている - LINQなしで同じことをして\0例のために働いても、それが理由StringBuilderを使用しての代わりにほとんどであるが、当然の入力を、変更されません。

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(); 
} 

null参照処理がありません。

tvanfossonのソリューションに触発されて、私はLINQに2回目のショットを与えました。

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

元々私の代わりに働いていなかったのは分かりませんが、String.Emptyはうまくいきました...私はLinqには参加していませんが、コンテキスト内で何をしていたのかは、私は自分のやり方だ...ありがとう – DRapp

3

「何も置き換えない」には、空の文字列に置き換えます。これはあなたに与えるでしょう:

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

より一般的なバージョンは文字列の拡張子です。他のものと同様に、これはC#では文字列が不変である代わりに、代わりに指定された置換文字で新しい文字列を返すため、変換は行われません。

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

これは、LINQを使用して問題を複雑にすると思われる場合です。これはシンプルでポイントです。

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>
関連する問題