C# 用C语言解析数学表达式#
作为一个项目,我想为C#中的数学表达式编写一个解析器。我知道这方面有很多库,但我想创建自己的库来学习这个主题 例如,我有一个表达式C# 用C语言解析数学表达式#,c#,regex,parsing,C#,Regex,Parsing,作为一个项目,我想为C#中的数学表达式编写一个解析器。我知道这方面有很多库,但我想创建自己的库来学习这个主题 例如,我有一个表达式 min(3,4) + 2 - abs(-4.6) 然后,我通过指定正则表达式并遍历试图匹配其中一个正则表达式的用户的表达式,从这个字符串创建令牌。这是从前面到后面进行的: private static List<string> Tokenize(string expression) { List<string>
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;
}
私有静态列表标记化(字符串表达式)
{
列表结果=新列表();
列表标记=新列表();
添加(“^\\(”;//匹配左括号
添加(“^([\\d.\\d]+)”;//匹配浮点数
添加(“^[&&|!]+”;//匹配运算符和其他特殊字符
tokens.Add(“^[\\w]+”;//匹配字和整数
tokens.Add(“^[,]”;//匹配项,
tokens.Add(“^[\\)]”;//匹配右括号
while(0!=表达式.Length)
{
bool-foundMatch=false;
foreach(令牌中的字符串令牌)
{
Match=Regex.Match(表达式、标记);
if(false==match.Success)
{
继续;
}
结果.添加(匹配.值);
expression=Regex.Replace(表达式,标记“”);
foundMatch=true;
打破
}
if(false==foundMatch)
{
打破
}
}
返回结果;
}
这很有效。现在,我希望用户能够在表达式中输入字符串。我在这里发现了一个问题,但是答案提供了正则表达式,它匹配表达式中任何地方的文本。但是,我只需要匹配表达式前面的第一个匹配项,这样我就可以保持token的顺序。
例如,请参见以下内容:
5+”小于“+10
应该给我代币吗
5
+
大于“
+
10
如果可能,我还希望能够输入转义字符,以便用户能够在字符串中使用字符“如”这是撇号\“
给我标记“这是撇号”
Wiktor Stribiżew对这个问题的回答看起来非常好,但我无法修改它,因此它只匹配开头和一个单词。感谢帮助!很有趣你提到了这个问题。我实际上(再次)采纳了我的答案,在这里为你工作;) 显示解决方案 正则表达式是
(?!\+)(?:"((?:\\"|[^"])*)"?)
我将代码更改为使用捕获组,以便能够以一种简单的方式而不是添加周围的引号。此外,循环会删除分隔标记的+
符号
关于您尝试了什么?不是event
“(.*?”
?(恭喜Wiktor现在成为参考;)会推荐类似或的内容。使用正则表达式解析复杂表达式是一个简单的游戏。谢谢!现在我可以继续:)