Като проект, искам да напиша анализатор за математически изрази в 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 е
(?!+)(?:"((?:\"|[^"])*)"?)
Промених кода, за да използвам групите за улавяне, за да може по прост начин не добавете околните котировки. Също така цикълът премахва +
знак за разделяне на жетони.
за разбирането