Regular expression used to split a unary operator

Although there are many regex questions related to my issue, none of them address my specific problem as I do not have parentheses in my expressions.

Let's take a look at an example: 1*2+3-99/50

I am trying to tokenize this expression in order to convert it to post-fix notation. My first attempt was to use split with regex like this:

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

It seems to work perfectly for binary operators but when dealing with unary operators, it falls short. I then attempted to utilize a lookahead to detect if a minus sign comes after another operator:

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

This method also works, but the caveat is that all numbers already have negative signs attached to them.

I've tried capturing operands with unary (-) operators separately and appending them to the final tokens, but it messes up the order which is crucial for evaluation. I also looked into conditional regex but it doesn't seem applicable in my scenario.

Is it feasible to split tokens containing negative signs in one single split action?

Answer №1

Consider using the \b delimiter for splitting

var numbers = '1*-2+-3-99/-50'.split(/(\b[-+*/])/);

console.log(JSON.stringify(numbers))

Answer №2

It is highly advisable to avoid using regular expressions for this task. The critical factor here is maintaining the correct order of operations, a feature that postfix notation can handle effortlessly but infix cannot.

Although this code snippet makes use of regular expressions, the core logic lies elsewhere:

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 /) *) +)"

To simplify the process, this function transforms subtractions into additions of negative numbers and divisions into multiplications by the inverse (1/n). To maintain the correct order of operations, we first split based on additions and subtractions, then proceed with each multiplication and division operation. The algorithm employs recursion to break down each segment and gradually build up the final answer from right to left.

This implementation solely handles addition, subtraction, multiplication, and division. There are no provisions for parentheses or exponents.

Answer №3

If you want to simplify the expression, consider making some modifications

this.expression = this.expression.replaceAll("&--", "+")
    .replaceAll("&++", "+")
    .replaceAll("&-+", "-")
    .replaceAll("&+-", "-");

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Encountering a registration error persistently: [TypeError: Network request failed]

Currently, I am in the process of developing an application using React for the frontend and node.js for the backend. However, I have encountered a persistent network error whenever I try to sign up or log in. What puzzles me is that when I test the API en ...

Shuffling Numbers in an Array After Removing an Element with AngularJS

I am working with a JSON array that contains tasks: tasks = [{taskcode:1, taskName:'abc'}, {taskcode:2, taskName:'abc1'}, {taskcode:3, taskName:'abc2'}, ..... ]; If I delete a task with the nam ...

Enhance information flow within pages using SWR in NextJS

Utilizing SWR in a NextJS project has been a great experience for me. I have successfully fetched a list of data on my index page and added a new entry to the data on my create page. Now, I am looking to take advantage of SWR's mutate feature to updat ...

Comparable to LINQ SingleOrDefault()

I frequently utilize this particular pattern in my Typescript coding: class Vegetable { constructor(public id: number, public name: string) { } } var vegetableArray = new Array<Vegetable>(); vegetableArray.push(new Vegetable(1, "Carrot")); ...

Struggling to access YouTube account via Google sign-in using Puppeteer framework

I am facing an issue with my puppeteer code where I am unable to proceed past the email page after clicking next due to some bot protection by Google advising me to "Try using a different browser...etc". Is there a way to bypass this using puppeteer? I h ...

Use an input to swap out a cube for a sphere in three.js

I need to switch the cube with a sphere of the same size, but when I try to add a function in JavaScript, the cube disappears. How can I adjust the dimensions of the cube? I am unsure how to connect the function modifie with the numeric inputs (length, w ...

Complete Form Validation Issue Unresolved by Jquery Validation Plugin

I'm facing an issue with the jQuery validation plugin while attempting to validate a form. Strangely, it only works for one input field. Can anyone suggest a solution? <script src="http://ajax.aspnetcdn.com/ajax/jquery.validate/1.11.1/jquery.valid ...

Removing a Group of Classes Based on Window Width Using Jquery/Javascript

Looking for assistance in optimizing this Jquery code to remove a list of classes from the DOM. The current implementation works, but I suspect there might be a more efficient way to achieve this without explicitly listing each class. jQuery(document).r ...

Combining variables in JavaScript using the concatenation method

There seems to be an issue with the variables in this code. Despite var1 being set to 3 and var2 being set to 10, the result is coming out as 310 instead of 13. var var1 = document.getElementById("start").value; var var2 = 10; var3 = var1 + var2; alert(v ...

Exporting data from JSON to a CSV file

I am attempting to find a solution for converting JSON objects into CSV files. I tried using a 'for...in' loop within another 'for' loop, but encountered an issue where the object properties and length are different. JSON data: [ {"n ...

What is the process for automatically activating the Enter key once moving to the next text input field?

Hey everyone, I am looking for a way to automatically trigger the enter button after the user switches to another HTML input type='text'. This is necessary for form validation. Below is the code snippet: <input type="text" class="form-contro ...

Attempting to deactivate the button across all pages within Datatables

Utilizing the Datatables JQuery plugin allows me to display data in a table format. In one column, I have incorporated buttons for editing rows. My aim is to make it so that when one button is clicked, the rest are deactivated. Below you will find my curr ...

Is there an HTML code block available for embedding an HTML snippet?

This has got to be one of the most irritating things I've encountered haha. So, I'm using prettify.js to add syntax coloring to my code, but whenever I try to encode HTML using either prettify.js or prism.js, I have to format it like this with a ...

How to use JavaScript and regex to control the state of a disabled submit button

I have a challenge where I need to activate or deactivate a submission button in a form called btn-vote using JavaScript. The button will only be activated if one of the 10 radio buttons is selected. Additionally, if the person-10 radio button is chosen, t ...

Tips for updating or deleting a ref value within the VueJS 3 composition api

I am utilizing a ref value in order to only trigger a click event when the ref value is changing. For instance, if I need to update/delete the array inside let myRef = ref([]);, should I simply access the proxy and carry out the operations like this : sel ...

Unable to process form submission with AngularJS + Stormpath

I am facing an issue with form submission. Even though I believe that the login and password data are being sent correctly, nothing happens when I submit the form. I am attempting to submit the form without using ngSubmit because it is not feasible in my s ...

Elusive shadow fails to appear in ThreeJS scene

<style> body { margin: 0; } </style> <script async src="https://unpkg.com/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="0267712f6f6d66776e672f716a6a6f716a6f717a333c343c71">[email protec ...

React Router v6 is throwing an error stating that within the <Routes> component, all children must be either a <Route> or <React.Fragment>

While the code snippet below may have worked perfectly fine in React Router v5, it's causing an error in React Router v6. Error: [Player] is not a <Route> component. All component children of <Routes> must be a <Route> or <React ...

Vue.js CSS class interpolation

Is there a way to apply CSS classes dynamically in Vue.js? {{ category.icon }} --> "icon1" I am trying to achieve the following: <i :class="category.icon" class="icon icon-"></i> The desired output should be: ...

The console logs indicate true, yet contradicts with a false assertion in the if statement

I am facing an issue with this code router.get("/timecard", ensureAuthenticated, async(req, res)=>{ users = await User.find(); console.log(req.user.cwlEmployee); if(req.user.cwlEmployee !== true){ req.flash('error_msg', &a ...