Как решить нераспознанную escape-последовательность?

У меня есть этот код для перехода между строками:

public static string getBetween(string strSource, string strStart, string strEnd)
{
    int Start, End;
    if (strSource.Contains(strStart) && strSource.Contains(strEnd))
    {
        Start = strSource.IndexOf(strStart, 0) + strStart.Length;
        End = strSource.IndexOf(strEnd, Start);
        return strSource.Substring(Start, End - Start);
    }
    else
    {
        return "";
    }
}

и это мои строковые данные:

FHTT-04ce1068 GP\u0001\u001b10001182-2100113j6J2-FTTH\b\u0006??0?-\u0006

Я хочу найти подстроку в этих данных, для этого напишите этот код:

string userName = getBetween(theData,"GP\u0001\u001", "\b\u0006??0?");

но получите эту ошибку:

Unrecognized escape sequence

измените этот код на этот:

string userName = getBetween(theData,@"GP\u0001\u001", "\b\u0006??0?");

но @ добавляет двойной escape-код для строки поиска, и этот код работает некорректно, как я могу решить эту проблему?
мой источник в этой ссылке:
Главный источник

Вам нужен @ для обоих аргументов, он у вас только для первого. (при условии, что файл действительно содержит escape-последовательности в виде текста)

Alex K. 11.04.2018 13:53

используйте \\ вместо \

vivek nuna 11.04.2018 13:53

@viveknuna не работает

stack stack 11.04.2018 13:56

@stackstack используйте оба параметра

vivek nuna 11.04.2018 13:57

В вводном тексте \u0001 - 1 символ или 6? Другими словами, что показывает NotePad (++)?

Henk Holterman 11.04.2018 13:57

@HenkHolterman 6 символов

stack stack 11.04.2018 13:59

Блокнот @HenkHolterman ++ показать \ u0001

stack stack 11.04.2018 14:00

@ не удваивает escape. Распечатайте значение с помощью оператора Debug.

paparazzo 11.04.2018 14:01

Надеюсь, вы не копировали из окна отладчика VisualStudio. Вам нужно посмотреть первоисточник.

Henk Holterman 11.04.2018 14:02

Поскольку ни один из ответов, похоже, не работает, пришло время для минимальный воспроизводимый пример.

Henk Holterman 11.04.2018 19:43
0
10
445
2

Ответы 2

Вы должны использовать \\ вместо \ или использовать @ с обоими параметрами метода getBetween

@stackstack: Не могли бы вы объяснить, почему это не работает для вас? Это известное решение возникшей ошибки.

Flater 11.04.2018 14:18

Вам нужно использовать символ дословный идентификатор (@) для обеих строк.

Со строковыми литералами это в основном означает, что символы \ считаются частью строки, в отличие от недословных строковых литералов, где они служат как escape-символы. (Обратите внимание, что в дословной буквальной строке, если вы хотите включить символ " как часть строки, вы избегаете его удвоением - var s = @"this is my ""special"" string";)

Причина, по которой ваш метод getBetween не возвращает ожидаемое значение, заключается в том, что сам метод содержит ошибку.

В вашем методе getBetween есть избыточный код, поэтому вот его улучшенная версия:

public static string GetBetween(string strSource, string strStart, string strEnd)
{
    var Start = strSource.IndexOf(strStart) + strStart.Length;
    var End = strSource.IndexOf(strEnd, Start);
    if (Start > strStart.Length -1 && End > -1)
    {
        return strSource.Substring(Start, End - Start);
    }
    return "";
}

И использование:

var source = @"FHTT-04ce1068 GP\u0001\u001b10001182-2100113j6J2-FTTH\b\u0006??0?-\u0006";
var target = GetBetween(source, @"GP\u0001\u001", @"\b\u0006??0?");

Результат:

b10001182-2100113j6J2-FTTH

Вы можете увидеть живую демонстрацию на rextester.

Вот что я улучшил по сравнению с вашим исходным методом:

// Capitalize the method name according to c# naming conventions.
public static string getBetween(string strSource, string strStart, string strEnd)
{
    int Start, End;
    // no point of checking if the string contains the values, IndexOf will return -1 if it doesn't.
    if (strSource.Contains(strStart) && strSource.Contains(strEnd))
    {
        // You don't need to specify that 0, IndexOf other overload already starts from zero.
        Start = strSource.IndexOf(strStart, 0) + strStart.Length;
        End = strSource.IndexOf(strEnd, Start);
        return strSource.Substring(Start, End - Start);
    }
    // else is redundant since there is a return statement in the if.
    else
    {
        return "";
    }
}

Обновлять

Проблема в том, что строка, по которой вы выполняете поиск, уже заполнена escape-последовательностями, включая пару \", поэтому добавление дословного идентификатора к этой строке фактически вызовет ошибку компиляции.

С другой стороны, если вы не используете дословный литерал в строке поиска, вы не можете использовать его в других строках - и это может вызвать проблему - поскольку это означает, что другие строки не могут быть просто случайными. части исходной строки - они должны иметь правильные escape-последовательности - а "GP\u0001\u001" нет - последняя escape-последовательность отсутствует, это последний символ - b, который вы получили в результатах, на самом деле является частью \u0001b - поэтому, если вы выполните поиск, например это:

var source = "\0PV?-M\0$??E?\b\0E\0\u0003???\0\0\u001d\u0011?)????\n\n\u0005g?H\a\u0015\u0003???\u0004s\u0003?S]pfX?\a?????H???U\u0006\0\0\u0001,.\u0006\0\u0011S?(\u0006\0\0\0\u00037\u0006Z???=\u0006\0\0\0%\u001a\u001e\0\0\0\t\u0001\u0018pppoe-session-id=39703\u001a)\0\0\0\t\u0001#client-mac-address=f08c.fbce.07fb\u001a=\0\0\r?\u000170 0/0/0:1250.1059 AN5516-01/3/6/2/0/3/FHTT04ce07f8 GP\u001aL\0\0\0\t\u0001Fcircuit-id-tag=0 0/0/0:1250.1059 AN5516-01/3/6/2/0/3/FHTT04ce07f8 GP,\n0019a97b\u0005\u0006\u0001\b?'W80 0/0/0:1250.1059 AN5516-01/3/6/2/0/3/FHTT04ce07f8 GP.\u001a>\0\0\0\t\u000280 0/0/0:1250.1059 AN5516-01/3/6/2/0/3/FHTT04ce07f8 GP.\u001e70 0/0/0:1250.1059 AN5516-01/3/6/2/0/3/FHTT04ce07f8 GP\u0001\u001b10001084-2100101Db75-FTTH\b\u0006??0?-\u0006\0\0\0\u0001\u001a\u0016\0\0\0\t\u0001\u0010vrf-id=default\u001a\u001f\0\0\0\t\u0001\u0019accounting-list=ibs-isg\a\u0006\0\0\0\u0001\u0006\u0006\0\0\0\u0002?\u0006\0\0\0C\u001a\"\0\0\0\t\u0001\u001cconnect-progress=IPCP Open*\u0006\u001c???4\u0006\0\0\0\u0001/\u0006\u0001Yb?+\u0006?kTJ5\u0006\0\0\0\b0\u0006\u0001???\u001a)\0\0\0\t\u0001#acct-input-octets-ipv4=4092795251\u001a(\0\0\0\t\u0001\"acct-input-packets-ipv4=22540221\u001a*\0\0\0\t\u0001$acct-output-octets-ipv4=1916952698\u001a$\0\0\0\t\u0001\u001eacct-output-gigawords-ipv4=8\u001a)\0\0\0\t\u0001#acct-output-packets-ipv4=28406963\u001a \0\0\0\t\u0001\u001aacct-input-octets-ipv6=0\u001a!\0\0\0\t\u0001\u001bacct-input-packets-ipv6=0\u001a!\0\0\0\t\u0001\u001bacct-output-octets-ipv6=0\u001a\"\0\0\0\t\u0001\u001cacct-output-packets-ipv6=0 \u0005ASR\u0004\u0006????_\u0012\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0)\u0006\0\0\0\0";
var target = GetBetween(
    source, 
    "GP\u0001\u001b", // Note I've added that `b`!
    "\b\u0006??0?");

Вы получите такой результат:

10001084-2100101Db75-FTTH

Почему в источнике нет ошибки без @, а в первом аргументе есть ошибка без @

Uthistran Selvaraj 11.04.2018 14:03

пожалуйста, подождите, чтобы проверить это.

stack stack 11.04.2018 14:06

@UthistranSelvaraj Потому что в этой строке нет недопустимого перехода. Сообщение об ошибке довольно ясное.

paparazzo 11.04.2018 14:06

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

Uthistran Selvaraj 11.04.2018 14:10

Если вы получаете строку из внешнего ресурса, такого как веб-сайт или файл, это больше не строковый литерал, поэтому вам не нужно его экранировать или дословно. Я добавил к своему вопросу некоторую информацию о символе @. Если этого недостаточно, вам следует перейти по ссылке и прочитать официальную документацию.

Zohar Peled 11.04.2018 14:20

спасибо, мой источник в этой ссылке, пожалуйста, просмотрите, что rextester.com/PWDCL23665

stack stack 11.04.2018 14:20

Я видел это. Проблема в том, что исходная строка уже заполнена escape-последовательностями; включая пару \" - как только вы измените его на дословную строку, " внутри больше не будет экранирован, и все произойдет сбой.

Zohar Peled 11.04.2018 14:31

Обновил свой ответ.

Zohar Peled 11.04.2018 14:40

Последняя часть ответа сразу после большого жирного заголовка «Обновление» :-)

Zohar Peled 11.04.2018 14:59

Другие вопросы по теме