2016-07-27 28 views
-1

我正在考虑为规则引擎项目构建计算解析器工具。将正则表达式分组为重复模式的不同部分

的计算需要我用string.split(”“)进入值的阵列的字符串的形式,分离值和运算符:

expression = "5 + 6 - 8" 
expression.split(' '); 

[0]:5 
[1]:+ 
[2]:6 
[3]:- 
[4]:8 

我的代码使用此阵列来得到答案3 - 目前我只是从左到右进行评估并处理运算符优先级。

我期待扩展计算字符串日期的工作 - 添加或从日期时间减去分钟,不幸的是我的DateTime有一个空间,所以我得到的结果是:

expression = "12/12/2016 12:00:00 + 30 - 10" 
expression.split(' '); 

[0]:12/12/2016 
[1]:12:00:00 
[2]:+ 
[3]:30 
[4]:- 
[5]:10 

当我真正想要的:

[0]:12/12/2016 12:00:00 
[1]:+ 
[2]:30 
[3]:- 
[4]:10 

我希望通过正则表达式来解决这个问题,所以我也可以验证串在同一时间,但不幸的是我创造它们的认识是有限的。

任何人都可以有一个正则表达式的例子,或任何关于如何可能做到这一点的建议 - 让数字和运算符分别存储在一个数组中?或者这是不可能的正则表达式?我会更好使用String.Substring()来取出数据吗?

编辑
SLN的解决方案解决了我的问题,我的最终代码看起来像这样:

var splitExp = Regex.Split(expression, @"[ ](?:(?=\D)|(?<=\D[ ]))"); 

其中给出:

expression = "12/12/2016 12:00:00" 
splitExp[0] = "12/12/2016 12:00:00" 

expression = "12/12/2016 12:00:00 + 30 - 10" 
splitExp[0] = "12/12/2016 12:00:00" 
splitExp[0] = "+" 
splitExp[0] = "30" 
splitExp[0] = "-" 
splitExp[0] = "10" 

这正是我一直在寻找。

+0

好吧,虽然它听起来太宽泛了,但可以试试'Regex.Split(表达式,@“(?!\ d + :)”)'。此外,请参阅[*是否有一个字符串数学评估器在.NET?*](http://stackoverflow.com/questions/355062/is-there-a-string-math-evaluator-in-net) –

+0

^这。使用负面的lookahead来让你的正则表达式正确匹配。给定的代码可能不是OP所需要的,但它可以作为一个起点,因为它至少非常接近OP的需求。 – Kadima

+0

另请参阅[*如何在C#*中解析数学表达式](http://stackoverflow.com/questions/2853907/how-to-parse-math-expressions-in-c)。 –

回答

-1

所有你需要的不是一个或另一个数字。
然后它不会匹配数字空格数字

使用正则表达式与拆分得到

[ ](?:(?=\D)|(?<=\D[ ]))

扩展

[ ]      # Space to split on 
(?:      # Check if space is valid 
     (?= \D)     # Either a non-digit after it 
    |       # or, 
     (?<= \D [ ])   # A non-digit before it 
) 

如果预计可变数量的空格
它改变这个结果 -

(?>[ ]+)(?:(?=\D)|(?<=\D[ ]+))

+0

我明白了,所以这就像是说“给我所有与模式不符的东西” - 这是一种寻找方式在我从未想过的问题上。 你的解决方案工作,所以我最终的代码看起来像这样: var splitExp = Regex.Split(expression,@“[](?:(?= \ D)|(?<= \ D []))” ); expression =“2016/12/12 12:00:00 + 30” splitExp [0] =“2016/12/12 12:00:00” splitExp [0] =“+” splitExp [0] =“30” 这正是我想要的。谢谢 - 我很感谢正则表达式的帮助和解释 – QTheIntro

0

有更好的方法可以做到这一点,但是您始终可以用日期中的空间替换令牌作为预处理输入的方式,然后在处理拆分索引时将替换替换回空间。示例: 用空格替换(([0-9]{2}/){2}[0-9]{4})()(([0-9]{2}:){2}[0-9]{2})并将[email protected]@[email protected]@$4替换为空格前的字符串,然后在继续处理每个索引处的拆分字符串时用实际空格替换@@[email protected]@

+0

因此,我不希望将空间视为具有特殊字符的空间,例如“12/12/2016 @ SPACE @ 12:00:00 + 30 - 10”,然后替换掉@ SPACE @解析前的实际空间。这对我很有用 - 尽管我同意它不会是最优雅的...... – QTheIntro