2012-03-05 3 views
4

Ну, я получил этот маленький метод:Escaping х из строк

static string escapeString(string str) { 
    string s = str.Replace(@"\r", "\r").Replace(@"\n", "\n").Replace(@"\t", "\t"); 
    Regex regex = new Regex(@"\\x(..)"); 
    var matches = regex.Matches(s); 
    foreach (Match match in matches) { 
     s = s.Replace(match.Value, ((char)Convert.ToByte(match.Value.Replace(@"\x", ""), 16)).ToString()); 
    } 

    return s; 
} 

Он заменяет "\ x65" из строки, которое я получил в аргументах [0].

Но моя проблема: «\\ x65» тоже будет заменена, поэтому я получаю «\ e». Я попытался выяснить регулярное выражение, которое проверит, есть ли еще одна обратная косая черта, но мне не повезло.

Может ли кто-нибудь дать подсказку?

+5

Вы изобретаете [Regex.Unescape] (http://msdn.microsoft.com/en-us/library/system.text.regularexpressions.regex.unescape.aspx)? – dtb

+0

Почему «\\ x65' не становится' \ e'? – bzlm

+0

@bzlm: потому что первый \ ускользает второй \ – dtb

ответ

0

Вы можете продолжить перематывать регулярные выражения вместе с такими вещами, как «\ s | \ w \ x (..)», чтобы удалить случай с \ x65. Очевидно, что это будет хрупким, поскольку нет гарантии, что ваша последовательность \ x65 всегда имеет пробел или символ перед ним. Это может быть начало файла. Кроме того, ваше регулярное выражение будет соответствовать \ xTT, что, очевидно, не является unicode. Рассмотрите возможность замены '.' с классом символов, подобным «\ x ([0-9a-f] {2})».

Если бы это был школьный проект, я бы сделал что-то вроде следующего. Вы можете заменить все комбинации «\» на другую маловероятную последовательность, например «@ !! @ @ @», запустите регулярное выражение и замены, а затем замените всю маловероятную последовательность на «\». Например:

String s = inputString.Replace(@"\\", @"[email protected][email protected][email protected]_"); 
// do all of the regex, replacements, etc here 
String output = s.Replace(@"[email protected][email protected][email protected]_", @"\"); 

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

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

Начать чтение здесь теории: http://en.wikipedia.org/wiki/Lexical_analysis

0

Используйте отрицательный взгляд-за:

Regex regex = new Regex(@"(?<!([^\]|^)\\)\\x(..)"); 

Это утверждает, что предыдущий символ не соло обратной косой черты, но без захвата в предыдущий символ (обходы не захватываются).

+0

Это не соответствует '\\\ x65', но, вероятно, должно быть. – hvd

+0

@hvd Я считал это, но надеялся, что никто не заметит :) Я думаю, что я исправил это. – Bohemian

+0

Теперь он совпадает с '\ x' в' \\ x65' в начале строки (так как ему не предшествует '[^ \] \\'), а также соответствует '\\\\ x65' , Обратная косая черта сбрасывается, если ей предшествует нечетное число обратных косых черт, и она не отображается, если ей предшествует четное число обратных косых черт. Регулярное выражение просто не является подходящим инструментом для этой работы :) – hvd

Смежные вопросы