Ответ 1
Пока вы поймаете очень специфические исключения, просто сделайте try/catch.
Исключения не являются злыми при правильном использовании.
Я разрешаю пользователям вводить регулярное выражение, соответствующее IP-адресам, для IP-фильтрации в соответствующей системе. Я хотел бы подтвердить, если введенные регулярные выражения действительны, так как многие пользователи будут беспорядочно работать с хорошими намерениями.
Я могу, конечно, сделать Regex.IsMatch() внутри try/catch и посмотреть, если он взорвется таким образом, но есть ли более разумные способы сделать это? Скорость не является проблемой как таковой, я просто предпочитаю избегать исключения исключений без причины.
Пока вы поймаете очень специфические исключения, просто сделайте try/catch.
Исключения не являются злыми при правильном использовании.
Я думаю, что исключения в этом случае в порядке.
Вот что я собрал:
private static bool IsValidRegex(string pattern)
{
if (string.IsNullOrEmpty(pattern)) return false;
try
{
Regex.Match("", pattern);
}
catch (ArgumentException)
{
return false;
}
return true;
}
Не без большой работы. Разбор регулярных выражений может быть довольно привлекательным, и в Framework нет ничего публичного для проверки выражения.
System.Text.RegularExpressions.RegexNode.ScanRegex() выглядит как основная функция, отвечающая за разбор выражения, но внутренняя (и в любом случае исключает исключения для любого недопустимого синтаксиса). Таким образом, вам потребуется переопределить функциональные возможности синтаксического анализа, что, несомненно, приведет к сбою при использовании крайних случаев или обновлений Framework.
Я думаю, что просто поймать ArgumentException - такая же хорошая идея, как вы, вероятно, в этой ситуации.
Неправильное регулярное выражение не является наихудшей причиной исключения.
Если вы не уходите в очень ограниченное подмножество синтаксиса регулярных выражений, а затем напишите регулярное выражение (или синтаксический анализатор) для этого - я думаю, что у вас нет другого способа тестирования, если он действителен, но попытаться построить конечный автомат из это и сделать что-то подходящее.
В зависимости от того, для кого цель предназначена для этого, я буду очень осторожен. Нетрудно создать регулярные выражения, которые могут вернуться к самим себе и съесть много процессора и памяти - они могут быть эффективным вектором Denial of Service.
У меня есть метод проверки правильности RegEx, но он просто обертывает регулярное выражение в Try/Catch. Я не уверен, есть ли лучший способ сделать это, но я не смог найти его.
В .NET, если вы не написали свой собственный парсер регулярных выражений (о котором я бы настоятельно советовал), вам почти наверняка понадобится обернуть создание нового объекта Regex с помощью try/catch.
Используя следующий метод, вы можете проверить, действует ли ваше выражение регулятора или нет. здесь testPattern - это шаблон, который вы должны проверить.
public static bool VerifyRegEx(string testPattern)
{
bool isValid = true;
if ((testPattern != null) && (testPattern.Trim().Length > 0))
{
try
{
Regex.Match("", testPattern);
}
catch (ArgumentException)
{
// BAD PATTERN: Syntax error
isValid = false;
}
}
else
{
//BAD PATTERN: Pattern is null or blank
isValid = false;
}
return (isValid);
}