c# - 用于验证算术表达式的正则表达式

标签 c# regex

我有一个算术表达式

string exp = "((2+3.1)/2)*4.456";


我想通过使用正则表达式进行验证。该表达式只能包含整数,浮点数,操作数和括号。

我如何生成正则表达式以进行验证,请帮助或提出任何其他验证该字符串的方法。

最佳答案

使用Perl / PCRE,我们可以借助如下结构的模式来验证这种简单的算术表达式:

expr = pnum ( op pnum )*
pnum = num | \( expr \)


其中,根据需要定义了numop。例如:

num = -?+\d++(?:\.\d++)?+
op = [-+*/]


这将为我们提供以下工作表达:

(?x)^ (?&expr) $

(?(DEFINE)
    (?<expr> (?&pnum) (?: (?&op) (?&pnum) )*+   )
    (?<pnum> (?> (?&num) | \( (?&expr) \) )   )
    (?<num>  -?+\d++(?:\.\d++)?+   )
    (?<op>   [-+*/]   )
)


但是,此类表达式不能与.NET正则表达式一起使用,因为它不支持(递归)后继调用(?&name)
而是.NET regex lib为我们提供了其特殊功能:balancing groups

使用平衡组,我们可以重写pnum中使用的必需的递归调用,并使用如下结构:

expr = pnum ( op pnum )* (?(p)(?!))
pnum = (?> (?<p> \( )* num (?<-p> \) )* )


我们在这里所做的是在每个数字前后允许任意数量的可选打开和关闭括号,计算打开括号(?<p> \( )的总数,从该数字(?<-p> \) )以及表达式的末尾减去闭合括号。确保开放括号的数量为0 (?(p)(?!))

(我相信这等效于原始结构,不过我还没有提供任何正式的证据。)

产生以下.NET模式:

(?x)
^
(?> (?<p> \( )* (?>-?\d+(?:\.\d+)?) (?<-p> \) )* )
(?>(?:
    [-+*/]
    (?> (?<p> \( )* (?>-?\d+(?:\.\d+)?) (?<-p> \) )* )
)*)
(?(p)(?!))
$


C# Example

using System;
using System.Text.RegularExpressions;

namespace RegexTest
{
    class Program
    {
        static void Main(string[] args)
        {
            var expressions = new string[] {
                "((2+3.1)/2)*4.456",
                "1",
                "(2)",
                "2+2",
                "(1+(2+3))",
                "-2*(2+-2)",
                "1+(3/(2+7-(4+3)))",
                "1-",
                "2+2)",
                "(2+2",
                "(1+(2+3)",
            };

            var regex = new Regex(@"(?x)
                ^
                (?> (?<p> \( )* (?>-?\d+(?:\.\d+)?) (?<-p> \) )* )
                (?>(?:
                    [-+*/]
                    (?> (?<p> \( )* (?>-?\d+(?:\.\d+)?) (?<-p> \) )* )
                )*)
                (?(p)(?!))
                $
            ");

            foreach (var expr in expressions)
            {
                Console.WriteLine("Expression: " + expr);
                Console.WriteLine("    Result: " + (regex.IsMatch(expr) ? "Matched" : "Failed"));
            }
        }
    }
}


输出:

Expression: ((2+3.1)/2)*4.456
    Result: Matched
Expression: 1
    Result: Matched
Expression: (2)
    Result: Matched
Expression: 2+2
    Result: Matched
Expression: (1+(2+3))
    Result: Matched
Expression: -2*(2+-2)
    Result: Matched
Expression: 1+(3/(2+7-(4+3)))
    Result: Matched
Expression: 1-
    Result: Failed
Expression: 2+2)
    Result: Failed
Expression: (2+2
    Result: Failed
Expression: (1+(2+3)
    Result: Failed

关于c# - 用于验证算术表达式的正则表达式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9443291/

相关文章:

c# - 在偏移处绘制图形

c# - 如何从azure AD应用程序客户端ID生成 token ?

c++ - 正则表达式忽略注释行 C++

python - 使用预定义的表在 r 中搜索 Dataframe 中的字符串并添加相应的列

objective-c - 与正则表达式匹配时是否可以忽略字符串中的字符

javascript - 如何使用 Javascript 正则表达式从可能的单词列表中获取单词的最后一次出现?

c# - 如何将大量数据加载到 map

c# - Crystal 报表条形码 128 转换器

c - 正则表达式:匹配c中的 float

c# - Mono for Android 完整版错误编译 Google Maps Library