【问题标题】:Regex challenge: changing formats of negative numbers正则表达式挑战:改变负数的格式
【发布时间】: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)ab 也可以被否定。冲洗并重复。
  • @RvdV79 在 math 的世界里,一切都是加法,而不是减法……积极思考。当您添加所有内容时,您只需按照数字行上数字符号的方向即可。 -3 + -3 表示在 -3 位置向左移动 -3。 -3 + +3 表示向右 3.

标签: c# regex parsing replace


【解决方案1】:

是的,您可以这样做,但只要有更改,您就必须调用替换操作,因为以下正则表达式只会替换单个一元运算符:

private static Regex _regex = new Regex(@"(?<=^|[-(+*/])-(?<value>\d+|\((?:[^\(\)]|(?<open>\()|(?<-open>\)))+?(?(open)(?!))\))", RegexOptions.Compiled);

private static string RemoveUnaryOperators(string input)
{
    var result = Regex.Replace(input ?? string.Empty, @"\s+", string.Empty);
    string tmp;
    do
    {
        tmp = result;
        result = _regex.Replace(result, @"(0-${value})");
    }
    while (result != tmp);

   return result;
}

DEMO

输出:

5*-3  ->  5*(0-3)
(5--5)-3  ->  (5-(0-5))-3
(5-------5)-3  ->  (5-(0-(0-(0-(0-(0-(0-5)))))))-3
-(1-2)-3  ->  (0-(1-2))-3

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-10-02
    • 2013-06-27
    • 1970-01-01
    • 2013-11-19
    • 1970-01-01
    • 2023-03-22
    • 2019-01-12
    • 1970-01-01
    相关资源
    最近更新 更多