Unescape избежал строки? - PullRequest
4 голосов
/ 18 июля 2011

Мы сохраняем конфигурацию ContentDelimiter (которую мы используем для разделения содержимого) в базе данных в виде строки (которая может быть «tab», т.е. \ t или новой строкой \ r \ n)

Позже мы хотели бы использовать этот конфиг, как бы я мог преобразовать \t (это строка, а не чат) в символ табуляции?

Пример:

string delimiterConfig =  config.GetDelimiter();
char[] delimiter = ConvertConfig(delimiterConfig);

Как будет выглядеть ConvertConfig, так что он будет анализировать все экранированные строки обратно в символы, чтобы строка \ t стала \t char.

Какие-нибудь элегантные решения без использования падежных операторов и замены?

Ответы [ 5 ]

4 голосов
/ 18 июля 2011

Если под «лучшим» решением вы имеете в виду быстрее:

static String Replace(String input)
    {
        if (input.Length <= 1) return input;

        // the input string can only get shorter
        // so init the buffer so we won't have to reallocate later
        char[] buffer = new char[input.Length];
        int outIdx = 0;
        for (int i = 0; i < input.Length; i++)
        {
            char c = input[i];
            if (c == '\\')
            {
                if (i < input.Length - 1)
                {
                    switch (input[i + 1])
                    {
                        case 'n':
                            buffer[outIdx++] = '\n';
                            i++;
                            continue;
                        case 'r':
                            buffer[outIdx++] = '\r';
                            i++;
                            continue;
                        case 't':
                            buffer[outIdx++] = '\t';
                            i++;
                            continue;
                    }
                }
            }

            buffer[outIdx++] = c;
        }

        return new String(buffer, 0, outIdx);
    }

Это значительно быстрее, чем при использовании Regex.Особенно, когда я проверил по этому входному сигналу:

var input = new String('\\', 0x1000);

Если под «лучше» вы имеете в виду легче читать и поддерживать, то решение Regex, вероятно, победит.Также могут быть ошибки в моем решении;Я не проверял это очень тщательно.

4 голосов
/ 18 июля 2011

Вот элегантное решение с оператором switch, Regex.Replace Method и пользовательским MatchEvaluator :

var input = @"This is indented:\r\n\tHello World";

var output = Regex.Replace(input, @"\\[rnt]", m =>
{
    switch (m.Value)
    {
    case @"\r": return "\r";
    case @"\n": return "\n";
    case @"\t": return "\t";
    default: return m.Value;
    }
});

Console.WriteLine(output);

Выход:

This is indented:
        Hello World
2 голосов
/ 18 ноября 2015

Для ограниченного набора базовых разделителей ASCII у вас также есть простое решение:

Regex.Unescape(input)

Вы можете прочитать все об этом в документации MSDN , но в основном это работает со всемиразделителей Regex и литералов пробелов.

Имейте в виду, что он генерирует неизвестные escape-последовательности.

1 голос
/ 16 января 2012

Если лучше, то вы имели в виду поддерживаемые escape-последовательности с отсутствием, поэтому я предлагаю вам проверить мой ответ на вопрос под названием: Оценить escape-строку , которая обрабатывает стандартные escape-последовательности, восьмеричные escape-последовательности и Escape-последовательности Юникода. Я надеюсь, что вы найдете это решение более элегантным и соответствующим вашим потребностям.

0 голосов
/ 18 июля 2011

А как насчет метода ToCharArray?

string x = "\r\n";
char[] delimeter = x.ToCharArray();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...