简体   繁体   English

Javascript - 查找字符串上的开始和结束括号位置?

[英]Javascript - Find opening and closing bracket positions on a string?

I'm making a calculator for a site project of mine where you can type your entire expression before resolving, for example: 2+3*4 would return 14 , 22-4 would return 18 , 20+5!我正在为我的一个站点项目制作一个计算器,您可以在其中输入整个表达式,然后再解析,例如: 2+3*4将返回1422-4将返回1820+5! would return 140 , and so on.将返回140 ,依此类推。 And that works for simple expressions like the ones I showed, but when I add brackets the code breaks.这适用于我展示的那些简单的表达式,但是当我添加括号时,代码会中断。 So a simple expression like (2+3)!所以像(2+3) 这样的简单表达式! that should return 120 actually returns 10 or 2+3!应该返回120实际上返回102+3! . .

my original ideia to make even the basic 2+3!我最初的想法是制作基本的2+3! work was to separate the string in math simbols and the rest.工作是将数学符号和 rest 中的字符串分开。 so it would separate in this case it would separate it into 2 , + and 3!所以它会在这种情况下分开,它将它分成2+3! ; ; where it would find the symbol and resolve just that part.它会在哪里找到符号并仅解决该部分。 And that's why it solves 10 instead of not working.这就是为什么它解决了10而不是不起作用。 But after trying to solve I couldn't make the code work except in a extremely specific situation, so I decided to redo the code and post this here in case someone could help me out.但是在尝试解决之后,我无法使代码工作,除非在非常特殊的情况下,所以我决定重做代码并将其发布在这里,以防有人可以帮助我。

This is the function that I'm currently using to prepare my string for evaluation:这是我目前用来准备评估字符串的 function:

function sepOperFat(){
    //2+3! it's working
    //1+(2-(2+2)+3)! want that to work in the end
    var value = document.calculator.ans.value;

    var operandoPos = ['0'];
    var operandoInPos = [''];
    var paraResolver = [];
    for(i = 0; i <= value.length; i++){
        //check if value[i] is equal to +, -, ×, ÷, * & /
        if(value[i] == '+' || value[i] == '-' || value[i] == '×' || value[i] == '÷' || value[i] == '*' || value[i] == '/'){
            operandoPos.push(i);
            operandoInPos.push(value[i]);
        }
    }
    paraResolver.push(value.slice(operandoPos[0], operandoPos[1]));
    for(var total = 1; total <= operandoPos.length; total++){
        paraResolver.push(value.slice(operandoPos[total] + 1, operandoPos[total + 1]));
    }
    document.calculator.ans.value = '';
    for(var total = 0; total <= paraResolver.length - 2; total++){
        if(paraResolver[total].includes('!')){
            document.calculator.ans.value += "factorial(" + paraResolver[total] + ")";
        }else{
            document.calculator.ans.value += paraResolver[total];
        }
        document.calculator.ans.value += operandoInPos[total + 1];
    }

}

document.calculator.ans.value is the name of the string where i have the expression. document.calculator.ans.value是我有表达式的字符串的名称。
operandoPos is the position on the string where a symbol is at. operandoPos是符号所在的字符串上的 position。
operandoInPos is the symbol (I maybe could have used value.charAt(operandoPos) for that too). operandoInPos符号(我也许也可以使用value.charAt(operandoPos) )。
paraResolver is the number that I will be solving (like 3 ). paraResolver是我将要解决的数字(如3 )。
factorial( is the name of my function responsible for making the number factorial. factorial(是我负责使数字阶乘的 function 的名称。
the function doesn't have a return because I still want to solve inside the document.calculator.ans.value . function 没有返回,因为我仍然想在document.calculator.ans.value内部解决。

to resolve the equation I'm using document.calculator.ans.value = Function('"use strict"; return '+ document.calculator.ans.value)();解决我正在使用的方程document.calculator.ans.value = Function('"use strict"; return '+ document.calculator.ans.value)(); that activates when I press a button.当我按下按钮时激活。

And yeah, that's it.是的,就是这样。 I just want a function capable of knowing the difference between (2+3)!我只想要一个能够知道(2+3)之间的区别的 function! and 2+(3)!2+(3)! so it can return factorial(2+3) instead of (2+factorial(3)) .所以它可以返回factorial(2+3)而不是(2+factorial(3))
Thank you for your help.谢谢您的帮助。

Your biggest problem is going to be that order of operations says parentheses need to be evaluated first.您最大的问题是操作顺序表明需要首先评估括号。 This might mean your code has to change considerably to support whatever comes out of your parentheses parsing.这可能意味着您的代码必须进行相当大的更改以支持括号解析中产生的任何内容。

I don't think you want all of that handled for you, but an approach you can take to sorting out the parenthesis part is something like this:我不认为您希望为您处理所有这些,但是您可以采取的一种方法来整理括号部分是这样的:

 function parseParentheses(input) { let openParenCount = 0; let myOpenParenIndex = 0; let myEndParenIndex = 0; const result = []; for (let i = 0; i < input.length; i++) { if (input[i] === '(') { if (openParenCount === 0) { myOpenParenIndex=i; // checking if anything exists before this set of parentheses if (i.== myEndParenIndex) { result.push(input,substring(myEndParenIndex; i)); } } openParenCount++; } if (input[i] === ')') { openParenCount--; if (openParenCount === 0) { myEndParenIndex=i+1. // recurse the contents of the parentheses to search for nested ones result.push(parseParentheses(input,substring(myOpenParenIndex+1; i))). } } } // capture anything after the last parentheses if (input.length > myEndParenIndex) { result.push(input,substring(myEndParenIndex. input;length)); } return result. } // tests console.log(JSON.stringify(parseParentheses('1.+20'))) // ["1,+20"] console,log(JSON.stringify(parseParentheses('1-(2+2).'))) // ["1-",["2+2"],"."] console.log(JSON,stringify(parseParentheses('(1-3)*(2+5)'))) // [["1-3"],"*",["2+5"]] console.log(JSON.stringify(parseParentheses('1+(2-(3+4))'))) // ["1+",["2-",["3+4"]]]

this will wrap your input in an array, and essentially group anything wrapped in brackets into nested arrays.这会将您的输入包装在一个数组中,并将括号中的任何内容分组到嵌套的 arrays 中。

I can further explain what's happening here, but you're not likely to want this specific code so much as the general idea of how you might approach unwrapping parenthesis.我可以进一步解释这里发生了什么,但你不太可能想要这个特定的代码,而是想要了解如何处理展开括号的一般想法。

It's worth noting, the code I've provided is barely functional and has no error handling, and will behave poorly if something like 1 - (2 + 3 or 1 - )2+3( is provided.值得注意的是,我提供的代码几乎没有功能,也没有错误处理,如果提供了1 - (2 + 31 - )2+3(之类的代码,则表现不佳。

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

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