2009-05-11 2 views
4

Есть ли быстрый способ (без явного прокрутки каждого символа в строке) и либо лишения, либо сохранения его. В Visual FoxPro есть функция CHRTRAN(), которая делает это отлично. Его на замену символа 1: 1, но если персонаж не находится в альтернативном положении, его разделили из последней строки. ExC# Зачистка/преобразование одного или нескольких символов

CHRTRAN ("Это будет тест", "он", "X")

вернется

"ThXs wXll быть эс"

Обратите внимание на оригинальный "я" преобразуется в «X», а нижний регистр «t» удаляется.

Я посмотрел на замену для аналогичного намерения, но не увидел вариант заменить ничем.

Я ищу, чтобы сделать некоторые общие процедуры для проверки нескольких источников данных, которые имеют разные типы ограничений ввода. Некоторые данные могут поступать из внешних источников, поэтому для проверки не требуется проверка на ввод в текстовое поле.

Благодаря

+1

CHRTRAN это странно API. –

+0

@Greg D - Только если вы никогда не работали с FoxPro. Я считаю, что TRANSLATE в PL/SQL Oracle работает одинаково. –

+0

Или оператор tr ///d Perl, если используется память. –

ответ

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

Приношу свои извинения. Я натолкнулся на это, ища эквивалент .NET для функций Python translate/maketrans, поэтому я думал о том, как эти функции работают. – 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(); 
} 

Отсутствует обращение к ссылке.

Вдохновленный решением tvanfosson, я дал 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

Не знаю, почему замена не работала для меня изначально, но 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>
Смежные вопросы