摘要:描述正则表达式在项目中的实际应用,介绍如何利用它来解析字符串。

  一、一点背景

  谌总和老谭这两个人,有不少相似的地方。比如说,在软件设计和实现的时候,都希望系统的逻辑能清晰地呈现出来,也是说,使软件具备清晰的结构。

  但这一次,老谭走向了自己的反面。

  讨论的是公式的管理问题。项目中的节点量、指标值等数据的计算,都会用到公式。公式中包含四则运算,也可以用括弧提高运算的优先级,参加运算的对象都是系统中的其他数值,如罐量、仪表量之类。

  谌总建议将公式的结构保存在数据库中,一个公式用到若干记录和字段,这样便于了解相互之间的引用关系。老谭则建议干脆一个公式一个字符串,用名字标识要引用的对象。由于老谭是具体干活的,谌总也乐于这样。

  于是,定义了公式的格式,如下面的例子所示:

  ($B'1车间一号表'+10-$G'一罐区二号罐'+$J'N-213号节点')*5

  其中 $ 是引导符,B、G、J是对象类型,分别表示仪表、罐、节点(用汉语拼音总是觉得有点土,是么?),后面跟上用引号引起来的对象名称。

  计算公式值的思路是,将公式中的对象找出来,用对象的值替换后,得到一个纯数字的计算公式,再找一个工具来计算这个公式的值。

  二、初的做法

  现在的问题是怎么解析公式,找出对象,再用对象的值替换公式的内容。

  这活儿交给了玉龙,他初采用的是传统的切割字符串的做法:

    private double EvaluateFormula(string formula)
    {
        foreach (var items in formula.Split('+'))
        {
            foreach (var item in items.Split('-'))
            {
                if (item.Trim()[0] != '$')
                {
                    continue;
                }

                var name = item.Replace("$", string.Empty);
                 
                string[] s = name.Split(''');
                switch (s[0])
                {
                    case "b":
                        formula = formula.Replace(item, GetMeterValue(s[1]));
                        break;
                    case "g":
                        formula = formula.Replace(item, GetTankValue(s[1]));
                        break;
                    case "j":
                        formula = formula.Replace(item, GetNodeValue(s[1]));
                        break;
                }
            }
        }

        return EvaluateExpression(formula);
    }