【发布时间】:2017-02-10 15:04:18
【问题描述】:
首先,我想我必须为我对正则表达式的了解不多而道歉(还)。 我已经搜索和搜索,但没有找到与我的具体挑战相匹配的解决方案。
现在问题来了:
我目前正在尝试开发解析器(意思是自己编写)。我想在考虑正则表达式的同时做到这一点。 到目前为止,我已经做了很多,但是,我遇到了一个小问题。一元减号和二元减号。
大约十年前,我在大学学到的是,这应该基于上下文。但是,我在手动操作时还使用了一个简单的技巧,那就是将每个一元减号写入不同的格式:
-3 = (0 - 3)
或
5 * -3 = 5 * (0 - 3)
有点棘手:
(5--5)-3 = (5 - (0 - 5)) - 3
现在,这是我的问题,是否有可能编写一个正则表达式,通过添加 括号将 一元减号 表达式转换为 二元减号 表达式和一个 0,就像上面提供的例子一样?
也许还有其他方法,但我在这里有点偏见......
评论: 首先,我开始用 MINUS 替换所有减号,例如:
expressionBuffer = "-(1-2)-3";
expressionBuffer = Regex.Replace(expressionBuffer, "-", "MINUS");
这会产生一个新的表达式缓冲区,如下所示:
MINUS ( 1 MINUS 2 ) MINUS 3
现在,我尝试通过应用以下正则表达式来捕获二进制“-”运算符:
expressionBuffer = Regex.Replace(
expressionBuffer,
@"(?<number>((\d+(\.\d+)?)))\s+MINUS",
"${number} -"
);
这会产生:
MINUS ( 1 - 2 ) MINUS 3
第一个 MINUS 显然是一元运算符(但第二个显然不是!)所以我现在正在寻找一种方法将其重写为以下 (first) 格式:
( 0 - ( 1 - 2) ) MINUS 3
但在这里我坚持将第一个一元减号处理为二进制减号,以便:
( 0 - ( 1 - 2) ) - 3
关于如何为此使用正则表达式的任何想法?
【问题讨论】:
-
类似this?
-
@RvdV79:我怀疑我的正则表达式方法是否只能在一般情况中解决问题。要检测减号是否为一元(运算符优先级)只是工作的一部分,您必须找出它的论点:
1*-(2+3*(4+5))->1*(0-(2+3*(4+5)))这意味着 pushdown automata跨度> -
为了加快速度,将所有内容转换为加法。从左到右进行多次传球。交替执行这两个步骤:1. 将所有
--转换为+,2. 将所有-( a - b)转换为+(-a -- b)。 a 和 b 也可以被否定。冲洗并重复。 -
@RvdV79 在 math 的世界里,一切都是加法,而不是减法……积极思考。当您添加所有内容时,您只需按照数字行上数字符号的方向即可。
-3 + -3表示在 -3 位置向左移动 -3。-3 + +3表示向右 3.