C # Разбор / преобразование одного или нескольких символов - PullRequest
4 голосов
/ 11 мая 2009

Существует ли быстрый способ (без необходимости явного циклического перебора каждого символа в строке) и его удаление или сохранение. В Visual FoxPro есть функция CHRTRAN (), которая делает это великолепно. Он заменяет символ 1: 1, но если в альтернативной позиции нет символа, он удаляется из последней строки. Ex

CHRTRAN («Это будет тест», «это», «X»)

вернется

"ThXs будет эс"

Обратите внимание, что исходное "i" преобразуется в "X", а нижний регистр "t" удаляется.

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

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

Спасибо

Ответы [ 7 ]

9 голосов
/ 11 мая 2009

Все, что вам нужно, это пара звонков на String.Replace () .

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

Обратите внимание, что Replace () возвращает новую строку. Он не изменяет саму строку.

5 голосов
/ 13 мая 2009

Здесь была моя последняя функция, и она отлично работает, как и ожидалось.

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;
}
5 голосов
/ 11 мая 2009

Это то, что вы хотите?

"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());
}
3 голосов
/ 11 мая 2009

Это тот случай, когда я думаю, что использование 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();
}
3 голосов
/ 11 мая 2009

Более общая версия как расширение строки. Как и другие, это не делает перевод на месте, так как строки неизменны в 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 голосов
/ 11 мая 2009

Чтобы заменить ничем, просто замените пустую строку. Это даст вам:

String str = "This will be a test";
str = str.Replace("i", "X");
str = str.Replace("t","");
0 голосов
/ 18 января 2017

  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);</p>

<code>        }

        return result;
    }
...