简体   繁体   English

用于验证数学方程的正则表达式

[英]Regular Expression for validating mathematical equation

I need to validate an expression in c# using regular expression. 我需要使用正则表达式在c#中验证表达式。

The string to be validated has following rules: 要验证的字符串具有以下规则:

  1. Only three variables can be used in the expression: [chair], [table], [fan] (Please note that square brackets are included. 表达式中只能使用三个变量:[椅子],[桌子],[风扇](请注意,包括方括号。
  2. Only four mathematical operators may be used: +, -, /, * 只能使用四个数学运算符:+,-,/,*
  3. Brackets may be used (we need to ensure that the brackets are placed correctly) 可以使用支架(我们需要确保支架放置正确)
  4. Float constants may be used: example, 10.55, 22.23, 3, etc. 可以使用浮点常量:例如10.55、22.23、3等。

The first target is to validate that the string entered follows the above rules. 第一个目标是验证输入的字符串是否遵循上述规则。

(Later, we may need to parse and calculate the value as well. But the question is basically about validation regex.) (稍后,我们可能还需要解析和计算值。但是问题基本上是关于验证正则表达式的。)

I like long esoteric regular expressions. 我喜欢深奥的正则表达式。 They make me feel all warm and fuzzy. 他们让我感到温暖和模糊。 However, I don't use them in my projects, because they usually don't belong in production code. 但是,我不在项目中使用它们,因为它们通常不属于生产代码。 I'm going to give you a regex that will do almost everything you are asking, and then I am going to explain why this is not a good idea. 我将给您一个正则表达式,它几乎可以满足您的所有要求,然后我将解释为什么这不是一个好主意。

It is based on the fact that you can't (or at least I couldn't think of how to) validate that an expression is correct, but you could use one to match malformed expressions. 它基于以下事实:您无法(或至少我无法想到如何)验证表达式是否正确,但可以使用一个表达式来匹配格式错误的表达式。 So here it is: 所以这里是:

(\[[a-z0-9]+\]).*?(?(1)(\[[a-z0-9]+\]).*?)(?(2)(\[[a-z0-9]+\]).*?)(?(3)(\[[a-z0-9]+\]).*?)|[/+*.-]{2,}|[^\[\]0-9a-z/+*.-]|(?>[0-9]+(?:\.[0-9]+)*)[^/+*-]|\[[^\]]+(?:\[|$)|\[[^a-z0-9]*[^a-z0-9\]]

Now take another look at that pattern... a really good look. 现在再来看一下这种模式……非常好看。 Because once you commit that to your code, you are responsible for it. 因为一旦将其提交到代码中,就应对它负责。

Problem #1 - Maintenance 问题1-维护

What happens when you change the spec? 更改规格会怎样? Let's say you wanted to allow (4) variables or allow boolean operators. 假设您要允许(4)个变量或允许布尔运算符。 How exactly will you alter this pattern? 您究竟将如何改变这种模式? I guarantee that my first attempt at modifying it would be a failure, and this isn't even as complicated as it can get. 我保证我第一次尝试修改它会失败,而且这还没有达到它的复杂程度。 Still, you should have seen how many times I broke this one when I was writing it. 不过,您在编写该书时应该已经看过我破解了多少本。

You could try posting again on SO, and maybe someone could decipher it. 您可以尝试在SO上再次发布,也许有人可以解密它。 Still, you'd have to do quite a bit of testing in order to make sure any revisions are correct. 不过,您必须进行大量测试才能确保所有修订都是正确的。 Which leads to... 这导致...

Problem #2 - Testing 问题2-测试

How do you debug any revisions? 您如何调试任何修订? This is why I said I don't use it in production code. 这就是为什么我说我不在生产代码中使用它的原因。 With procedural code, you can set break points and use QuickWatch to figure out what's going on, but regular expressions are like a black box. 使用过程代码,您可以设置断点并使用QuickWatch找出正在发生的事情,但是正则表达式就像黑盒子。 If there is a bug in this pattern, it will be far more difficult to fix it. 如果此模式中有错误,将很难修复它。 And even if you understand completely what is going on, good luck ever being able to hand off this monster to fellow developer. 即使您完全了解发生了什么,也有幸将这个怪物交给其他开发人员。

I'd encourage you to study the expression above, try to figure out how and why it works, even play with modifications. 我鼓励您研究上面的表达式,尝试弄清楚它的工作方式和原因,甚至进行修改。 But for your own sanity and that of anyone you work with , do not incorporate this or any of its bastard siblings into your project. 但是出于您自己和与您一起工作的任何人的理智 ,请不要将此或其中的任何混蛋纳入您的项目。 aioobe gave you a good place to start looking into the correct way to do this. aioobe为您提供了一个开始寻找正确的方法的好地方。 I'd highly recommend following that path. 我强烈建议您遵循该路径。

3. Brackets may be used (we need to ensure that the brackets are placed correctly) 3.可以使用托架(我们需要确保正确放置托架)

Keep in mind that the language of words with balanced brackets is not regular . 请记住,带括号的单词的语言不规则

This means that if you indeed really want to use regular expressions for the task, you'll have to rely on regex-engine specific extensions . 这意味着,如果您确实确实想为任务使用正则表达式,则必须依赖于正则表达式引擎特定的扩展

Basically, regular expressions are not a good tool for this task . 基本上,正则表达式不是完成此任务的好工具 You should have a look at context free grammars, and presumably parser-generators which can produce parsers for C#. 您应该看看上下文无关的语法,以及大概可以为C#生成解析器的解析器生成器。

Further SO reading: SO的进一步阅读:

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM