#c# #regex #validation
#c# #регулярное выражение #проверка
Вопрос:
Мне нужно проверить логические выражения, такие как,
( ( var1 == var2 ) amp;amp; ( var2 >= var4 || var1 > var5 ) )
( var1 < var2 )
( var1 == var2 || var3 != var4 )
Все фигурные скобки, переменные и логический оператор разделены одним ПРОБЕЛОМ.
Мне нужно регулярное выражение для его синтаксического анализа.
Или подскажите мне какую-нибудь логику для проверки этого с помощью C #.
Спасибо.
Комментарии:
1. Из-за вложенных скобок это не подходит для регулярных выражений. Я бы посоветовал вам убрать «используя регулярное выражение» из вашего заголовка, тогда больше людей с C # обратят внимание на ваш вопрос.
2. Обязательно ли использовать регулярные выражения? Не могли бы вы использовать сторонний инструмент, такой как ANTLR?
Ответ №1:
Либо создайте свой собственный анализатор, либо смотрите ниже (находится здесь). Вам нужно будет немного изменить его, чтобы учесть переменные, но это не должно быть слишком сложно. Либо проанализируйте их перед передачей в функцию, либо измените функцию на исключение имен переменных и значений.
using System.CodeDom.Compiler;
using Microsoft.CSharp;
using System.Reflection;
/// <summary>
/// A simple function to get the result of a C# expression (basic and advanced math possible)
/// </summary>
/// <param name="command">String value containing an expression that can evaluate to a double.</param>
/// <returns>a Double value after evaluating the command string.</returns>
private double ProcessCommand(string command)
{
//Create a C# Code Provider
CSharpCodeProvider myCodeProvider = new CSharpCodeProvider();
// Build the parameters for source compilation.
CompilerParameters cp = new CompilerParameters();
cp.GenerateExecutable = false;//No need to make an EXE file here.
cp.GenerateInMemory = true; //But we do need one in memory.
cp.OutputAssembly = "TempModule"; //This is not necessary, however, if used repeatedly, causes the CLR to not need to
//load a new assembly each time the function is run.
//The below string is basically the shell of a C# program, that does nothing, but contains an
//Evaluate() method for our purposes. I realize this leaves the app open to injection attacks,
//But this is a simple demonstration.
string TempModuleSource = "namespace ns{"
"using System;"
"class class1{"
"public static double Evaluate(){return " command ";}}} "; //Our actual Expression evaluator
CompilerResults cr = myCodeProvider.CompileAssemblyFromSource(cp,TempModuleSource);
if (cr.Errors.Count > 0)
{
//If a compiler error is generated, we will throw an exception because
//the syntax was wrong - again, this is left up to the implementer to verify syntax before
//calling the function. The calling code could trap this in a try loop, and notify a user
//the command was not understood, for example.
throw new ArgumentException("Expression cannot be evaluated, please use a valid C# expression");
}
else
{
MethodInfo Methinfo = cr.CompiledAssembly.GetType("ns.class1").GetMethod("Evaluate");
return (double)Methinfo.Invoke(null, null);
}
}
Комментарии:
1. @GeorgeDuckett Ты это тестировал?
2. Нет, и, судя по исходному потоку, требуется хотя бы одно редактирование, будет протестировано и обновлено.
3. Спасибо, Джордж, но мне просто нужно проверить данное выражение, например, имеет ли выражение правильный формат или нет. Я не хочу оценивать выражение. вот почему я спросил в Regular Expression.
4. Вы могли бы использовать описанный выше метод для его оценки. Если это не удается, то это недопустимое выражение.
5. У меня есть только строка, которая является логическим выражением. я не могу присвоить значения переменным. Итак, прежде чем перейти к оценке, мне нужно его проверить.
Ответ №2:
Если бы я делал это и хотел сделать это как регулярное выражение, я бы создал многопроходный алгоритм, при каждом проходе устраняющий проверенный вложенный случай (например, замените проверенный «(x == y )» на «x»
Возможно, что-то, начинающееся с: s/bw $op w b/^^MAGICTOKEN^^/g
Тогда любой /$ op / был бы незаконным.
Затем сфокусируйтесь в цикле на каждом парене: s/(( [^)] ))/^^MAGICTOKEN^^/
Сосредоточившись на $ 1, уменьшите: s/ $MAGICTOKRE $BOOL $MAGICTOKRE / ^^MAGICTOKEN^^ /
запустите reduce в цикле, пока он не перестанет уменьшаться. Если $1 ne " ^^MAGICTOKEN^^ "
, ошибка
После цикла фокусировки, скорее всего, $expression ne "^^MAGICTOKEN^^"
будет указывать на ошибку.
Комментарии:
1. Я предлагаю вам заменить ваш код на C #, чтобы OP мог это понять 😉