/ / Parsing математически изрази в C # - c #, regex, parsing

Разработване на математически изрази в C # - c #, regex, parsing

Като проект, искам да напиша анализатор за математически изрази в C #. Знам, че има библиотеки за това, но искам да създам свой собствен, за да науча за тази тема.

Като пример имам израз

min(3,4) + 2 - abs(-4.6)

Тогава създавам токен от този низ, като посочвам регулярни изрази и минавам през израза от потребителя, опитващ се да съвпада с един от регежите. Това се прави от предната страна на гърба:

    private static List<string> Tokenize(string expression)
{
List<string> result = new List<string>();
List<string> tokens = new List<string>();

tokens.Add("^\(");// matches opening bracket
tokens.Add("^([\d.\d]+)"); // matches floating point numbers
tokens.Add("^[&|<=>!]+"); // matches operators and other special characters
tokens.Add("^[\w]+"); // matches words and integers
tokens.Add("^[,]"); // matches ,
tokens.Add("^[\)]"); // matches closing bracket

while (0 != expression.Length)
{
bool foundMatch = false;

foreach (string token in tokens)
{
Match match = Regex.Match(expression, token);
if (false == match.Success)
{
continue;
}

result.Add(match.Value);
expression = Regex.Replace(expression, token, "");
foundMatch = true;

break;
}

if (false == foundMatch)
{
break;
}
}

return result;
}

Това работи доста добре. Сега искам потребителят да може да въведе низове в израза. Намерих въпрос в това Regex тоkenize въпрос но отговорът дава регенерация, която съответства натекст навсякъде в израза. Но имам нужда от това, за да съвпадна само с първото събитие в предната част на израза, за да мога да запазя реда на символите. Като пример вижте следното:

5 + " is smaller than " + 10

трябва да ми дадете жетоните 5 + " is greater than " + 10

Ако е възможно, бих искал също така да вляза в евакуационни знаци, така че потребителят да може да използва знака "в низове, като "This is an apostrophe " " ми дава знак "This is an apostrophe " "

Отговорът от Wiktor Stribiżew на този въпрос изглеждаше наистина добър, но не можах да го променя, така че то само съвпада в началото и само една дума.

Отговори:

0 за отговор № 1

Странно, че споменавате този въпрос. Всъщност приех (още веднъж) мой Отговорете там, за да работите за вас тук;)

Тук е цигулка показващо разтвора.

Regex е

(?!+)(?:"((?:\"|[^"])*)"?)

Промених кода, за да използвам групите за улавяне, за да може по прост начин не добавете околните котировки. Също така цикълът премахва + знак за разделяне на жетони.

за разбирането