简体   繁体   English

使用正则表达式拆分一元运算符

[英]Unary operator split using regex

There is a lot of related regex questions but none of them solves my problem, since I don't have parenthesis in my expressions.有很多相关的正则表达式问题,但没有一个能解决我的问题,因为我的表达式中没有括号。

I have a string mathematical expression for example: 1*2+3-99/50我有一个字符串数学表达式,例如: 1*2+3-99/50

I need to tokenize the expression to convert the expression to post-fix notation.我需要标记表达式以将表达式转换为后修复符号。 So I used split with regex as follows:所以我使用 split 和 regex 如下:

'1*2+3-99/50'.split(/([+\-*/])/)                   // operands have no unary (-)
// ['1', '*', '2', '+', '3', '-', '99', '/', '50'] 

That works fine.这很好用。 But working with unary operators, it doesn't work.但是使用一元运算符,它不起作用。 So I tried to use lookahead to detect if a minus comes after another operator:所以我尝试使用前瞻来检测减号是否出现在另一个运算符之后:

'1*-2+-3--99/-50'.split(/([+\-*/])(?=-)/               // all operands have unary (-)
// ['1', '*', '-2', '+', '-3', '-', '-99', '/', '-50']

This also works but only because all numbers already have negative sign.这也有效,但只是因为所有数字都已经有负号。

I have tried to capture first the operands with unary (-) operators to append it to the final tokens, but I lost order which is important in the evaluating phase.我曾尝试首先使用一元 (-) 运算符捕获操作数以将其附加到最终标记,但我丢失了在评估阶段很重要的顺序。 Also tried to read about conditional regex, but doesn't make much of a sense in my case.还尝试阅读条件正则表达式,但在我的情况下没有多大意义。

Is it possible to split tokens containing negative signs on one single split?是否可以在一次拆分中拆分包含负号的令牌?

Try splitting with \\b尝试用\\b分割

 var a = '1*-2+-3-99/-50'.split(/(\\b[-+*/])/); console.log(JSON.stringify(a))

First, you really don't want to do this with regular expressions.首先,你真的不想用正则表达式来做这件事。 Importantly, you need to keep track of the order of operations, something that postfix can take for granted but infix cannot.重要的是,您需要跟踪操作的顺序,这是 postfix 可以认为是理所当然的,但 infix 不能。

This sample code uses regular expressions, but that's not where the real logic resides:此示例代码使用正则表达式,但这不是真正的逻辑所在:

 function toPostfix(equation) { let output = ""; let additions = equation.replace(/\\b\\s*-/g, "+-").split(/\\+/); if (additions.length > 1) { output = "+)"; for (let a = additions.length - 1; a >= 0; a--) { output = toPostfix(additions[a]) + " " + output; } return "( " + output; } else { if (equation.match(/^1\\/-?[0-9]+$/)) { return "( 1 " + equation.substring(2) + " /)"; } let multiplications = equation.replace(/\\//g, "*1/").split(/\\*/); if (multiplications.length > 1) { output = "*)"; for (let m = multiplications.length - 1; m >= 0; m--) { output = toPostfix(multiplications[m]) + " " + output; } return "( " + output; } else { return equation; } } } console.log(toPostfix('1*2+3-99/50')); // "( ( 1 2 *) 3 ( -99 ( 1 50 /) *) +)"

For simplicity, this converts subtractions to additions of negative numbers and divisions to multiplications of inverted ( 1/n ) numbers.为简单起见,这将减法转换为负数的加法,并将除法转换为倒数 ( 1/n ) 的乘法。 To observe order of operations, we have to split by the additions/subtractions first, then break down to each multiplication/division.为了观察运算顺序,我们必须先按加法/减法进行拆分,然后再分解为每个乘法/除法。 I used a recursive call to break down each piece and build up the answer incrementally, right to left.我使用递归调用来分解每个部分并从右到左逐步建立答案。

This only accounts for + - * and / .仅占+ - */ No parentheses, no exponents.没有括号,没有指数。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM