Страницы

Поиск по вопросам

четверг, 25 октября 2018 г.

Как программно экранировать управляющие символы в строке?

Мне необходимо вставить в паттерн регулярного выражения:
$@"^(?:[^\p{{L}}]|[{exclusion}])+$" //Цель: Запретить использование каких либо букв в строке, кроме тех что заданы в переменной - exclusion
строковую переменную:
string exclusion;
в которой все управляющие символы были бы экранированы, что позволило бы избежать ошибок связанных с работой регулярного выражения.
Я нашел метод Regex.Escape(). Но он не удовлетворяет моим потребностям. Например, если значение exclusion = @"[text]" передать в метод Regex.Escape() то он вернет строку "\\[text]". После вставки данной строки в паттерн вместо переменно exclusion:
$@"^(?:[^\p{{L}}]|[{exclusion}])+$" //Цель: запретить использование каких либо букв в строке, кроме тех что заданы в переменной - exclusion
он приобретает следующий вид:
$@"^(?:[^\p{{L}}]|[\[text]])+$"
В результате регулярное выражение работает неправильно. Подозреваю, что причина в лишнем символе - ]
Скажите пожалуйста как экранировать все управляющие символы в строке? Есть ли какой то другой способ кроме метода - Regex.Escape()? Может быть я его как то неправильно использовал и не замечаю своей ошибки?


Ответ

Regex.Escape экранирует те знаки, которые считаются специальными вне символьных классов:
Escapes a minimal set of characters (\, *, +, ?, |, {, [, (, ), ^, $, , #, and white space) by replacing them with their escape codes. (Экранирует минимальный набор знаков (\, *, +, ?, |, {, [, (, ), ^, $, , # и пробельный символ) путём замены на их escape-коды)
На самом деле, внутри символьных классов специальными считаются только следующие символы:
^ - может означать исклбчающий тип символьного класса, если находится сразу после открывающей [ ] - закрывает символьный класс \ - экранирует специальные символы - - задаёт диапазон символов или "вычитание символьных классов"
Для экранирования этих знаков достаточно использовать
exclusion.Replace("\\", @"\\").Replace("^", @"\^").Replace("-", @"\-").Replace("]", @"\]")
или
Regex.Replace(exclusion, @"[]^\\-]", "\\$&")
Решение:
var pattern = $@"^(?:[^\p{{L}}]|[{Regex.Replace(exclusion, @"[]^\\-]", "\\$&")}])+$";
Или (так как [^\p{L}] = \P{L}):
var pattern2 = $@"^[\P{{L}}{Regex.Replace(exclusion, @"[]^\\-]", "\\$&")}]+$";

Комментариев нет:

Отправить комментарий