一个自定义表达式的正则表达式解析

前端之家收集整理的这篇文章主要介绍了一个自定义表达式的正则表达式解析前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。


最近做了一个关于导入Excel数据的简单工具,设计思路如下: 

  1.使用XML描述配置关系

  2.引入简单表达式/函数对数据进行转换,处理

  3.支持灵活的扩展功能.


对EXCEL的转换配置定义如下:

<transform id="ts1" source="s1" target="t1">

<columns>

<column name="ID" dataType="int" type="autoint"/>

<column name="SITECODE" source="#Replace([$.2,$.1,$.3],[c1],[SiteName,RiverName],[SiteCode])" dataType="String"/>

<column name="SITECODE2" source="#Replace([$.2,c1,SiteCode)" dataType="String"/>

<column name="SITENAME" source="$.断面名称" dataType="String"/>

<column name="SAMPLINGTIME" source="#DateTime([$.采样日期],[yyyy-MM-01])" dataType="String"/>

<column name="SAMPLINGTIME2" source="#DateTime($.采样日期,yyyy-MM-01)" dataType="String"/>

<column name="SAMPLINGTIMESTR" source="#Date($.采样日期,[yyyy年MM月dd日])" dataType="String"/>

<column name="W_TEMP" source="$.4"/>

<column name="PH" source="$.5"/>

<column name="DO1" source="$.6"/>

<column name="CODcr" source="$.7"/>

<column name="NH4_N" source="$.8"/>

<column name="CODMN" source="$.9"/>

<column name="WaterGrade" source="#REPLACE([$.10],[c2],[name],[code])"/>

<column name="WaterGrade2" source="#REPLACE($.10,c2,name,code)"/>

<column name="WaterQuality" source="$.10"/>

<column name="TBR" source="#GET([s4,s5],[0],[1])"/>

<column name="SHR" source="#GET([s4,[3])"/>

<column name="YWZGFZR" source="#GET([s4,[6])"/>

<column name="TBRQ1" source="#SUBSTRING([#GET([s4,[3,4],5)],[5])"/>

<column name="TBRQ2" source="#SUBSTRING(#GET([s4,3,5),5)"/>

<column name="TBRQ3" source="#SUBSTRING(#GET([s4,[1-3],simsun;color:#002060;"> <column name="TBRQ" source="#DATETIME(#.TBRQ3,yyyy-MM-dd)"/>

<column name="REMARK" source="IMPORT"/>

<column name="ADDTIME" source="%NOW%"/>

<column name="UPDATETIME" source="%NOW%"/>

</columns>

</transform>

其中,source中的各种#,$,还有%等的字符串,为自定义的处理函数/表达式/常量,为了简单,现阶段函数表达式调用,只支持嵌套一层,上面代码中的(#SUBSTRING(#GET...)

定义的优先级规则为: 函数->表达式->常量


source的内容解析, 起初使用基于字符串匹配的方式, 勉强凑合工作, 但是马上就遇到了问题:


  源:   #Replace([$.2,[SiteCode])


解析目标: ReplaceFunctionExpression

Arguments[0]-> ExpressionCollection[3]->DataItemExpression

Arguments[1]-> c1 : StringExpression

Arguments[2]-> ExpressionCollection[2]->StringExpression

Arguments[3]-> SiteCode : StringExpression


  如上:函数的参数之间是用逗号隔开的,但是参数有可能是另一个表达式,或者一个数组[,],这样子,使用切分字符串的方式来解析函数的参数(尤其是参数为其他函数/表达式)就有问题了


记得数据结构中有中缀表达式和后缀表达式解析的算法,应该是可以实现本例的要求,但是时间有限,也不需要一个很强大的功能,所以还是没有采用,最后的解决方案,还是采用正则表达式来解析.


最终构造的正则表达式为:


@"\[?\#(?<fn>\w+)\((?<fp>(.*?)+)\)\]?|\[(?<fp2>([-\$\.\#%\w]+,)*[-\$\.\#%\w]+)\]|\[?(?<fp3>[-\$\.\#%\w]+)\]?"


测试的样例字符串:


//#GET([s4,[5],[#GET2([s6,s7],8,9)],[100],110,[$.1,s31,s41,s51,你好],weixq,[$.中国,$H.5,#.99],$.22,#DateTime([$.采样日期],[yyyy-MM-01]),[yyyy-MM-01]


输出的匹配结果:


Result:12

1.Success:[True],Index:[0],Length:[17],Value:[#GET([s4,5)].

2.Success:[True],Index:[18],Length:[3],Value:[[5]].

3.Success:[True],Index:[22],Length:[20],Value:[[#GET2([s6,9)]].

4.Success:[True],Index:[43],Length:[5],Value:[[100]].

5.Success:[True],Index:[49],Value:[110].

6.Success:[True],Index:[53],Value:[[$.1,你好]].

7.Success:[True],Index:[74],Value:[weixq].

8.Success:[True],Index:[80],Length:[16],Value:[[$.中国,#.99]].

9.Success:[True],Index:[97],Length:[4],Value:[$.22].

10.Success:[True],Index:[102],Length:[33],Value:[#DateTime([$.采样日期],[yyyy-MM-01])].

11.Success:[True],Index:[137],Length:[12],Value:[[yyyy-MM-01]].

12.Success:[True],Index:[150],Value:[[ND,%ND,%ND%,ND%]].


其中解析的结果做为下一轮函数/表达式的输入,继续解析,直到不能在分解.


希望能给解析自定义字符串的朋友们一点启发:)

猜你在找的正则表达式相关文章